2010-11-18 15 views
4

私はBrian GoetzによってJCIPを読んでいます。 CAS命令を使用してノンブロッキングカウンタの実装について説明します。私は、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; 
    } 
} 

答えて

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()カウンタの現在の値を取得し、誰もがされていない場合カウンタを同時に更新しようとすると、がtrueになるため、値はv+1(つまりインクリメントされます)に設定され、oldが返されます。ループはv == old以降終了します。

v = value.get()の直後に他の誰かがカウンタをインクリメントしたとすると、old == vはfalseになり、メソッドはすぐに更新された値である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を変更しようとする他のスレッドによって失われないことを知ることができます。

関連する問題