我正在研究Java书中的并发包。我不太了解这本书关于CAS操作的内容。以下代码示例是本书中的线程安全counter
类。
public class Counter{
private AtomicInteger count = new AtomicInteger();
public void increment(){
count.getAndIncrement(); //atomic operation
}
....
}
这是本书所说的内容。
实际上,即使像
getAndIncrement()
这样的方法仍然需要执行几个步骤。这个实现现在是线程安全的原因是CAS。 CAS代表Compare And Swap。大多数现代CPU都有一组CAS指令。现在发生的事情的基本概述如下:
- 存储在count中的值将复制到临时变量。
- 临时变量递增。
- 将当前计数值与原始值进行比较。如果未更改,则将旧值换为新值。
醇>
好的,我得到了关于多个步骤的说法。我所不能得到的是在列举的步骤中发生的事情。
- 存储在count中的值将复制到临时变量。
醇>
那个临时变量在哪里?它是在主存中,注册吗?或者这是否特定于CPU架构?
- 将当前计数值与原始值进行比较。如果未更改,则将旧值换为新值。
醇>
原始值存储在哪里?它不能是临时变量。那个人正在被修改,对吧?我错过了什么?
由于
答案 0 :(得分:0)
要比较的值被加载到两个+寄存器中(在您的示例中为三个)。然后它可能会使用CMPXCHG8B
这样的指令(部分)描述为
将EDX:EAX与m64进行比较。如果相等,则设置ZF并将ECX:EBX加载到m64。否则,清除ZF并将m64加载到EDX:EAX。
上面的第三个值可能位于不同的注册表中,例如ECX
(或EBX
)或其他某个位置(不是EAX
或EDX
)。您可以参考Compare and Swap上的Wikipedia条目了解其他实现(不一定使用汇编程序)。