这是为什么您的示例不是线程安全的示例。最初,_x = 0
. 假设您Increment
并行运行Assign
。如果方法是线程安全的,则结果应该是100
(如果在分配之前执行增量)或101
(如果在分配之后执行增量)。
(编辑:请注意,每个线程都有自己的工作堆栈!)
Thread 1 (executing Increment) Thread 2 (executing Assign 100)
-----------------------------------------------------------------
read _x onto stack (= 0)
put 100 on top of stack
write top of stack to _x (= 100)
increment top of stack (= 1)
write top of stack to _x (= 1)
_x
是现在1
,既不是100
也不是101
。
当然,可能是您的增量方法被编译器编译为单个原子操作。但是你不能依赖这个,除非你使用的编译器特别保证。
如果使用锁,会发生以下情况:
Thread 1 (executing Increment) Thread 2 (executing Assign 100)
-----------------------------------------------------------------
lock (success)
read _x onto stack (= 0)
lock (lock already taken;
| wait until Thead 1's lock is released)
increment top of stack (= 1) |
write top of stack to _x (= 1) |
unlock |
+> (success)
put 100 on top of stack
write top of stack to _x (= 100)
unlock
结果是现在100
。基本上,锁确保两个锁定的块不重叠。