2010-11-18 73 views
4

我一直在阅读Brian Goetz的JCIP。他解释了使用CAS指令实现一个非阻塞计数器。我无法理解如何使用CAS指令发生增量。任何人都可以帮我理解这一点。CAS and Non Blocking Counter

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; 
    } 
} 

回答

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将为真,因此该值设置为v+1(即递增),并返回old。该循环自v == old终止。

假设其他人在我们做了v = value.get()之后递增了计数器,那么old == v将是错误的,并且该方法将立即返回old,这是更新的值。由于v != old现在,循环继续。

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作为预期(这就是循环所做的)。

这样,调用者可以知道增量操作不会被其他线程尝试在同一时刻修改value而丢失。