日期:2014-05-18  浏览次数:20887 次

线程原子性操作问题
代码:
class TestNoInterLocked {
  private long i;
  private Dictionary<string, bool> diction = new Dictionary<string,bool>();
  private EventWaitHandle e = new EventWaitHandle(false, EventResetMode.ManualReset);
  public void Test() {
  for (int j = 0; j < 10; j++) {
  Thread t = new Thread(new ThreadStart(Test1));
  t.Name = "Thread "+j;
  diction.Add(t.Name, false);
  t.Start();
  }
  e.WaitOne();
  Console.WriteLine("i====================={0}",i);
  }
  public void Test1() {
  int k =0;
  while (k++ < 150) {
  i++; //这个地方不是原子性操作,也就是某个线程可能正要赋值时,被其它线程打断,
//也就是两个线程可能只对i的值加了一次,因此我觉得i应该是小于等于1500的
//那么我为什么每次执行打出i的值都是1500呢,请指教哈
  Console.WriteLine(Thread.CurrentThread.Name+"="+i);
  }
  diction[Thread.CurrentThread.Name] = true;
  bool b = true;
  foreach (string key in diction.Keys) {
  b = b & diction[key];
  }
  if (b)
  e.Set();
  }
  [MTAThread]
  public static void Main()
  {
   
   
  TestNoInterLocked tNo = new TestNoInterLocked();
  tNo.Test();
   
  Console.ReadLine();
  }
  }

------解决方案--------------------
你机器的cpu数还不至于导致出现这种情况。一个cpu基本上是不会出现的。

另外每个线程只循环150次太少,启动线程也是需要时间的,可能第二个线程还没起来,第一个线程的150次已经做完了。
------解决方案--------------------
探讨
你机器的cpu数还不至于导致出现这种情况。一个cpu基本上是不会出现的。

另外每个线程只循环150次太少,启动线程也是需要时间的,可能第二个线程还没起来,第一个线程的150次已经做完了。

------解决方案--------------------
楼主似乎不清楚为什么那样操作不是原子性操作,你要是知道了那个原理,就不会问这种问题了。

首先我要指明,加入你的变量i不是long,而是int型,那么你那个肯定是原子操作了。那么区别就在于该变量的高32位的操作,long型的整数还有高32的操作,而int型整数是没有的,只有当你的数据有可能存放到了那个高32位的地址上时,才会出现原子性被破坏,而你现在的数据完全没有超过Int32的范围啊,自然不可能出现任何问题。
------解决方案--------------------
探讨
楼主似乎不清楚为什么那样操作不是原子性操作,你要是知道了那个原理,就不会问这种问题了。

首先我要指明,加入你的变量i不是long,而是int型,那么你那个肯定是原子操作了。那么区别就在于该变量的高32位的操作,long型的整数还有高32的操作,而int型整数是没有的,只有当你的数据有可能存放到了那个高32位的地址上时,才会出现原子性被破坏,而你现在的数据完全没有超过Int32的范围啊,自然不可能出现任何问题。

------解决方案--------------------
探讨
引用:
楼主似乎不清楚为什么那样操作不是原子性操作,你要是知道了那个原理,就不会问这种问题了。

首先我要指明,加入你的变量i不是long,而是int型,那么你那个肯定是原子操作了。那么区别就在于该变量的高32位的操作,long型的整数还有高32的操作,而int型整数是没有的,只有当你的数据有可能存放到了那个高32位的地址上时,才会出现原子性被破坏,而你现在的数据完全没有超过Int32的范围啊,自然不可…