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