我一直在读约瑟夫·阿尔巴哈里的这本关于穿线的书:
http://www.albahari.com/threading/
在第2部分中,我找到了这个例子:
http://www.albahari.com/threading/part2.aspx#_When_to_Lock
以上是上述例子:
class ThreadUnsafe
{
static int _x;
static void Increment() { _x++; }
static void Assign() { _x = 123; }
}
线程安全版本:
class ThreadSafe
{
static readonly object _locker = new object();
static int _x;
static void Increment() { lock (_locker) _x++; }
static void Assign() { lock (_locker) _x = 123; }
}
我无法理解为什么 Assign 方法不是线程安全的。不应该在32位和64位架构上进行整数分配是原子操作吗?
答案 0 :(得分:10)
赋值是 atomic ,因为任何读取线程都会看到123或前一个值 - 而不是某个中间值。但是,在存在两个内存障碍之前,线程不能保证线程会看到新值:写入线程中的写入内存屏障,以及读取线程中的读取内存屏障。
如果您有两个这样的线程(在_x
公开或内部之后,以便可以从其他类型的课程中读取 - 或者使用ThreadSafe
类中的代码):< / p>
// Thread 1
Console.WriteLine("Writing thread starting");
ThreadSafe.Assign();
Console.WriteLine("Writing thread done");
// Thread 2
Console.WriteLine("Reading thread starting");
while (ThreadSafe._x != 123)
{
// Do nothing
}
Console.WriteLine("Reading thread done");
...没有保证线程2可以完成,因为线程2可能不会&#34;看到&#34;线程1的分配。