一、volatile关键字

  volatile是最简单的一种同步方法,当然简单是要付出代价的。它只能在变量一级做同步,volatile的含义就是告诉处理器, 不要将我放入工作内存, 请直接在主存操作我。(【转自www.bitsCN.com 】)因此,当多线程同时访问该变量时,都将直接操作主存,从本质上做到了变量共享。

  能够被标识为volatile的必须是以下几种类型:(摘自MSDN)

  • Any reference type.
  • Any pointer type (in an unsafe context).
  • The types sbyte, byte, short, ushort, int, uint, char, float, bool.
  • An enum type with an enum base type of byte, sbyte, short, ushort, int, or uint.
    1 public class A
    2 {
    3 private volatile int _i;
    4 public int I
    5 {
    6 get { return _i; }
    7 set { _i = value; }
    8 }
    9 }

    但volatile并不能实现真正的同步,因为它的操作级别只停留在变量级别,而不是原子级别。如果是在单处理器系统中,是没有任何问题的,变量在主存中没有机会被其他人修改,因为只有一个处理器,这就叫作processor Self-Consistency。但在多处理器系统中,可能就会有问题。 每个处理器都有自己的data cach,而且被更新的数据也不一定会立即写回到主存。所以可能会造成不同步,但这种情况很难发生,因为cach的读写速度相当快,flush的频率也相当高,只有在压力测试的时候才有可能发生,而且几率非常非常小。

     二、lock关键字

      lock是一种比较好用的简单的线程同步方式,它是通过为给定对象获取互斥锁来实现同步的。它可以保证当一个线程在关键代码段的时候,另一个线程不会进来,它只能等待,等到那个线程对象被释放,也就是说线程出了临界区。用法:

    1 public void Function()
    2 {
    3     System.Object lockThis = new System.Object();
    4     lock(lockThis)
    5     {
    6         // Access thread-sensitive resources.
    7     }
    8 }

    提供给 lock 关键字的参数必须为基于引用类型的对象,该对象用来定义锁的范围。在上例中,锁的范围限定为此函数,因为函数外不存在任何对该对象的引用。严格地说,提供给 lock 的对象只是用来唯一地标识由多个线程共享的资源,所以它可以是任意类实例。然而,实际上,此对象通常表示需要进行线程同步的资源。例如,如果一个容器对象将被多个线程使用,则可以将该容器传递给 lock,而 lock 后面的同步代码块将访问该容器。只要其他线程在访问该容器前先锁定该容器,则对该对象的访问将是安全同步的。

  • 使用 lock 关键字通常比直接使用 Monitor 类更可取,一方面是因为 lock 更简洁,另一方面是因为 lock 确保了即使受保护的代码引发异常,也可以释放基础监视器。这是通过 finally 关键字来实现的,无论是否引发异常它都执行关联的代码块。

     1 System.Object obj = (System.Object)x;
     2 System.Threading.Monitor.Enter(obj);
     3 try
     4 {
     5     DoSomething();
     6 }
     7 finally
     8 {
     9     System.Threading.Monitor.Exit(obj);
    10 }

    三.AutoResetEvent

     1 using System;
     2 using System.Threading;
     3 
     4 class ThreadingExample
     5 {
     6     static AutoResetEvent autoEvent;
     7 
     8     static void DoWork()
     9     {
    10         Console.WriteLine("   worker thread started, now waiting on event...");
    11         autoEvent.WaitOne();
    12         Console.WriteLine("   worker thread reactivated, now exiting...");
    13     }
    14 
    15     static void Main()
    16     {
    17         autoEvent = new AutoResetEvent(false);
    18 
    19         Console.WriteLine("main thread starting worker thread...");
    20         Thread t = new Thread(DoWork);
    21         t.Start();
    22 
    23         Console.WriteLine("main thrad sleeping for 1 second...");
    24         Thread.Sleep(1000);
    25 
    26         Console.WriteLine("main thread signaling worker thread...");
    27         autoEvent.Set();
    28     }
    29 }

     

posted on 2013-02-22 17:03  马小跳  阅读(166)  评论(0编辑  收藏  举报