我一直在读Brian Goetz的JCIP。他解释了使用CAS指令实现非阻塞计数器。我无法理解如何使用CAS指令进行增量。任何人都可以帮我理解这一点。
public class CasCounter {
private SimulatedCAS value;
public int getValue() {
return value.get();
}
public int increment() {
int v;
do {
v = value.get();
}
while (v != value.compareAndSwap(v, v + 1));
return v + 1;
}
}
答案 0 :(得分:4)
value.compareAndSwap(v, v + 1)
等效于以下内容:(有关详细信息,请参阅compare-and-swap)
int old = value.val;
if (old == v) {
value.val = v + 1;
}
return old;
现在v = value.get()
获取计数器的当前值,如果没有其他人同时尝试更新计数器,old == v
将为真,因此该值设置为{{1 (即递增)并返回v+1
。循环从old
开始终止。
假设其他人在我们v == old
之后递增了计数器,那么v = value.get()
将为false,并且该方法将立即返回old == v
,这是更新后的值。从old
开始,循环继续。
答案 1 :(得分:3)
compareAndSwap()
方法将以原子方式执行以下操作:
- determine if `value` is equal to `v`
- if so, it will set `value` to `v+1`
- it returns whatever `value` was when the method was entered (whether or not `value` was updated)
调用者可以检查value
是否是他们在被叫compareAndSwap()
时所期望的内容。如果是,则调用者知道它已被更新。如果它不是预期的那样,调用者知道它没有被更新,并将再次尝试,使用value
的“新”当前值作为预期(这就是循环正在做的事情)。 / p>
这样,调用者可以知道增量操作不会被尝试同时修改value
的其他线程丢失。