AQSエントリ

AQSについて

路径:java.util.concurrent.locks.AbstractOwnableSynchronizer。

定義:AQSは、ロック機能を達成するためにint型とFIFO待ち行列(双方向リンクリストの実装)の状態を維持することによって修飾揮発提供フレームシンクロナイザを

説明:AQSキュー同期、抽象クラスは、ベースフレームを構築するために使用され、同期同様の効果(または同期成分)ロックされた継承される方法を主に使用され、その後、状態を維持するための抽象メソッドを実装し、ReentrantLockの(内部クラスのよう継承は)AQSの認識に基づいています。

2つのコア

コアの方法:同期は、(取得を提供する)とリリース()は、2つの方法、同期状態法、いずれかを得るために、イタリアを知っている名前が表示が解除され、キーが作動状態です。

公共の最終ボイド取得(int型引数){ 
        場合(tryAcquire(引数)&&!
            acquireQueued(addWaiter(Node.EXCLUSIVE)、引数))
            selfInterrupt(); 
    }

最終リリースブールパブリック(int型のArg){ 
        IF(tryRelease(アルギニン)){//同期ステータスが正常に解放
            ノードH =ヘッドと、
            IF(!= nullの&& h.waitStatus H = 0)
                //即時放出ヘッドノード
                unparkSuccessor( H); 
            trueに戻る; 
        } 
        falseに復帰; 
    }

主な実装方法:tryAcquire(int型の引数)とtryRelease(int型引数)を取得の上にあると私たちは実装を完了するために必要なコールを、解放します。tryAcquire(int型引数)、彼の値を変更するには、状態を得ることであるtryRelease(int型引数)ここで解放状態です。

 

AQSクラス構造:

 

 

 

 

 

図1の主要メンバー

1:状態は、これはまた、彼の価値手段が取得したり、ロックを解除変更することができます同期ステータスとして知られているスレッド間の資源のための競争です。

CASは、同期の状態を操作するための3つの操作を提供します

  • getStateを()
  • SETSTATE()
  • compareAndSetState()

 

2:二重リンクリストの操作のためのノードのヘッドノードの尾と頭点ノードとエンド・ノード。

3:内部クラスノード、ノードの二重リンクリストは、実際には、二重に2ノードへの参照を設定するノードを達成するために、リストにリンク

最終ノードクラス{静的
  ノード次に、次のノードの
  ノードプレ;前のノードの 
  スレッドスレッド、現在のスレッド
  INTウェイトステート、ノードのノード現在の状態、及び上記同期状態の状態が独立述べ。
  ノードnextWaiter;リア前記
}

4:INNER ConditionObjectのは、待ち行列の動作を同期させるため、キュー待ちのオブジェクト(と同期等価である)と通知()、およびAQS ConditionObjectのオブジェクトが使用されます。

 

3:統合

1:tryAcquire()は状態(CAS変化値)を得ることができ、それがロックを取得することを意味する場合は、最初の呼び出しは、スレッド実行取得()このメソッドに行きます、あなたはAさんに直接コードを実行することができます。

それが失敗した場合、それはチェーン・ノードの末尾に設定されている現在のスレッドAこれには、ノードを作成します。ノードウェイトステート前に現在のノードが、予め指定された状態(-1)になるまでスピンの期間続いて、ロックを取得しようと、スレッドは、このスレッドが中断されパーク()です。だから、あなたがいずれかのノードのリリースの前に、オフホールド、スピンを持っていないか、中断され、ノードの後ろのウェイクアップ動作unparkをがあるでしょう。私はここで記述されたソースコードを見に行く、非常にシンプルですが、非常に複雑であり、他への参照https://www.cnblogs.com/iou123lg/p/9464385.html

公共の最終ボイド取得(int型引数){ 
        場合(tryAcquire(引数)&&!
            acquireQueued(addWaiter(Node.EXCLUSIVE)、引数))
            selfInterrupt(); 
    }

2:オブジェクトAQSに同期キューヘッドと組成の尾の上で、同期キューおよび待ち行列、複数の対応する二重リンクリストは、同期の動作状態を保存するために使用され;そして私はここで待ちキューは、あることを強調したいですこれは、この内部クラスに依存していたConditionObject

パブリッククラスConditionObjectのは、条件実装
条件キューの/ **最初のノードを。* /
プライベート過渡ノードfirstWaiter。
/ **状態のキューの最後のノード。* /
プライベート過渡ノードlastWaiter。

 

ここでは、それはまた、nextWaiterフィールドで、ノードが継承された上で見ることができ、キューを待って頭と尾にラウンドロビンリストfirstWaiterとlastWaiterポイントで、次の構造体へのnextWaiterポイントがケースです。

ノードの待ち行列が生成され、新しいAQSは、複数のオブジェクトがキューの複数を有することを意味するオブジェクトを、条件ことができ、各キューは、条件に該当します

例えば条件1 =新しい条件()、condition1.await()

ノードnode = addConditionWaiter()。
INT savedState = fullyRelease(ノード)。
int型interruptMode = 0;
一方、(isOnSyncQueue(ノード)!){
LockSupport.park(本)
(!(interruptMode = checkInterruptWhileWaiting(ノード))= 0)であれば
ブレーク。
}

最初は彼女にlastWaiterとfirstWaiterポイントを聞かせて、現在のスレッドに基づいてリストの条件1にノードノードを作成します。

それから私は、リソースを解放するために行く解放状態、縮小操作を行います。ここでは、リソースの解放は、同期キューの最初のノードを削除すること、およびノー​​ドの背面をウェイクアップします。

自己ループの期間続いて、それは、次に、現在のスレッドを中断していない場合、ノードは、同期キューがあるか否かを判断することを決定します。あなたは、国家のために再競合しなければならない場合。通常、この新しい待ちキューノードが同期キューに存在しない、それは呼び出し信号()メソッドがない限り、中断され、同等の(オブジェクトに通知)

信号()

この方法は、(つまり、削除)キューfirstWaiterを待っている条件1行こう、と彼は、同期キューが待っているのキューの先頭から同期キューの最後に移動されました。

 

借入:

https://www.cnblogs.com/iou123lg/p/9464385.html

https://www.jianshu.com/p/da9d051dcc3d

 



   

 

おすすめ

転載: www.cnblogs.com/xlblog/p/11575433.html