CASスピンvolatile変数

1234 ワード

まず、AtomicIntegerクラスのgetAndIncrementのソースコードを見てみましょう.
     public final int getAndIncrement() {
                 for (;;) {
                       int current = get();  //  AtomicInteger 
                     int next = current + 1;  //  1
                     if (compareAndSet(current, next))   //  compareAndSet 
                         return current;
                 }
             }

このコードは巧みに書かれています.
1,compareAndSetメソッドは,まず現在値がcurrentに等しいか否かを判断する.
2現在の値=currentの場合、AtomicIntegerの値は他のスレッドによって変更されていないことを示します.
3、現在の値の場合!=Currentは、AtomicIntegerの値が他のスレッドによって変更されたことを示し、このとき再びループ再比較に入る.
   
getAndIncrementメソッドでは、現在のvalue属性値を取得し、valueに1を加えてローカルのnext変数に値を付与します.しかし、この2つのステップは非スレッドで安全ですが、内部にはデッドサイクルがあり、成功するまでcompareAndSet操作を続けます.つまり、修正の根本はcompareAndSetメソッドにあります.
compareAndSet()メソッドで呼び出されたのはsunであることがわかる.misc.Unsafe.compareAndSwapInt(Object obj,long valueOffset,int expect,int update)メソッド
compareAndSwapIntは、CPUのCAS命令に基づいて実現される.したがって、CASベースの動作はブロックされていないと考えられ、1つのスレッドの失敗または停止は、他のスレッドも失敗または停止を引き起こすことはありません.またCAS操作はCPU原語なので性能が良い.
以上,getAndIncrement()法は原子操作ではない.彼と他の関数がvalueの更新に有効であることを保証しただけです.
彼が利用しているのは衝突検出に基づく楽観的な同時戦略である.この楽観はスレッド数が非常に多い場合,失敗の確率が指数的に増加することが想像できる.