zoukankan      html  css  js  c++  java
  • 多线程 C#解决方案小结

    与多线程相关的两个常见的需要解决的问题是:临界资源保护和线程间的同步依赖,每一种语言都提供了自己的一套设施(有的语言可能需要借助OS的API)来解决这两个问题,C#提供了更方便灵活的解决方案,首先C#可以允许我们在不同的级别上加锁,也就是说我们可以控制加锁的粒度。其次,C#提供了一套内置的线程安全的容器,方便我们的使用。

    一.不同级别(Level)上的同步:
    1.object level 同步
    对应的class必须从ContextBoundObject继承(同步上下文context,使所有的方法调用能被截获),并且在
    class上运用SynchronizationAttribute 。

    2.Method level 同步
    System.Runtime.CompilerService空间包含的一些属性将影响CLR在运行期间的行为。特性MethodImplAttribute可以用于需要进行同步控制的方法上。

    3.code segment level 同步
    (1)Monitor类(主要是静态方法)
    Monitor.Enter(obj)//获得加在对象obj上的锁
    ...
    Monitor.Exit(obj)//释放锁
    //上面两句之间的代码相当于lock(obj){...}

    Monitor.TryEnter(obj)//该方法立即返回,如果返回值为false,则接下来不需要Monitor.Exit(obj)。

    //以下几个方法用于线程间的交互 ==》 解决同步依赖
    Monitor.Wait(obj)//等待脉冲消息。释放对象上的锁并阻塞当前线程,以后只有其它线程调用Pulse或PulseAll时才会给它再次获得锁的机会
    Monitor.Pulse(obj)//发射脉冲消息( 只有得到锁后才能发射,而且发射不会自动释放锁)
    Monitor.PulseAll(obj)

    注意:
    (1)Monitor 锁定对象,只能在Enter()和Exit()之间的代码块中调用Wait和Pulse

    (2)不能在一个线程中获得锁,而在另一个线程中释放锁。这样会产生锁丢失。 获得锁和释放锁应该在同一个线程中完成。

    (3)lock语句
    lock(obj)
    {
        需要进行同步的代码
    }

    (4)ReaderWriterLock类
        实现单写多读程序的锁。
    AcquireReaderLock()//当没有写程序线程占用锁时,就可获得锁
    AcquireWriterLock()//当没有任何读写程序线程占用锁时,才可获得锁
    ReleaseReaderLock()
    ReleaseWriterLock()

    (5)ManualResetEvent
    Set()方法将状态设置为有信号
    Reset()将其设置为无信号
    WaitOne()将阻塞到其有信号为止,若调用WaitOne的时刻就是有信号的,将不会阻塞

    (6)AutoResetEvent
    与ManualResetEvent的区别是,AutoResetEvent.WaitOne()会自动改变事件对象的状态,即AutoResetEvent.WaitOne()每执行一次,事件的状态就改变一次。有信号-->无信号;无信号-->有信号

    说明:
    (1)无论是Monitor还是lock、ReaderWriterLock都只对引用类型的对象有效,因为引用类型的对象有一个隐藏的sync#字段,该字段的作用就是作为加锁的标记。
    (2)上述的各种设施中,只有Monitor 和ManualResetEvent/AutoResetEvent 能解决线程间的同步依赖问题,而其它的设施主要用于解决临界资源共享。

    4.member level同步
    (1)Interlocked类(主要是静态方法)
        同步一个由许多线程共享的变量。
    Decrement(ref int);//使变量减1
    Increment(ref int);//使变量加1
    //以上两个方法仅针对类int变量
    Exchange(ref object, object);

    (2)ThreadStaticAttribute
        该特性用于修饰静态变量,被该特性修饰的静态变量在每个线程中都有自己的副本。

    二.创建线程安全的对象
    Hashtable h = Hashtable.Synchronized(new Hashtable()) ;
    ArrayList等容器也提供类似操作。

  • 相关阅读:
    Build MySQL 5.7.4 in RedHat
    glibc-2.19 之 strlen 实现
    [部署问题列表]
    [数据链路排查]
    VS配置本地IIS以域名访问
    SQL系列函数——数学函数
    面向对象编程的几个原则
    SQL系列函数——字符串函数
    SQL数据类型
    DHtmlx组件获取选中行的某一列对应的值
  • 原文地址:https://www.cnblogs.com/luluping/p/1647471.html
Copyright © 2011-2022 走看看