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