ロックカテゴリ:
まず、悲観的ロック
ヘビー級のロックは、閉塞につながることができます。他のスレッドが保留中のブロックされるデータにアクセスする必要がある場合に、データ、他のスレッドが変更されることがすべてを変更するたびに、そう(読み取りロック、書き込みロック、行ロックなど)を、ロックします。(Javaで同様の同期など):排他ロックミューテックス
第二に、楽観的ロックは
、基本的にロックフリー、より効率的、非ブロック、ノーウェイト、再試行されていない
通常時にデータベーステーブルの設計、バージョン(バージョン)フィールド、毎回があるでしょう書き込み操作を行う際に、最初に同じデータを行うために他の誰かがある場合は、このバージョンの変更、修正を行うための条件として数が、彼らはまた、この時点でのバージョン番号(例:1)を、更新することを、バージョン番号を確認します修正、バージョン番号は変更できません。この場合につながっ+1を、である、それは再試行します。(SASイデオロギー的なロックフリーのメカニズムでJavaに似ています)
リエントラント(同期ロックとロックがリエントラントである)
、再帰的ロック、ロックは、デッドロックの問題解決するために、再び新たなロックを作成することなく、内部処理方法の外側の層に渡すことができる
(アトミック視界+)同期をロック内蔵(ヘビー)
同期方法:
まず、このロックの使用です。
同期のボイドパブリック(){セール
IF(trainCount> 0){
System.out.printlnは( -にThread.currentThread()のgetName()+ "の販売" +(100 trainCount + 1 ")+ 。チケット");
trainCount--;
}
}
II同期ブロック(推奨):
同期(オブジェクト)//このオブジェクトは、任意のオブジェクトであってもよい
{
コードを同期する必要
}
静的同期機能。
静的ボイドセールパブリック(){
同期(ThreadTrain3.class){
IF(trainCount> 0){
System.out.printlnは(にThread.currentThread()のgetName()+ "の販売" +(100 - 。trainCount + 1 ) +「チケット」);
trainCount--;
}
}
}
静的ロック同期機能は、機能を使用するバイトコードファイルオブジェクトがgetClassメソッドによって取得することができる属し、それは現在のクラス名の.classによって表すことができます。
表示ロックラッチ(軽量)
ReentrantLockの()リエントラントロックの
手動施錠ロック()は、ロックUNLOCK()リリース
のtryLock()
のパラメータのtryLock(長い時間、TimeUnitで単位)とを 、
最初に長い時間を待って、第二時間の単位は
、戻り結果を対応する長い待ち時間
パラメータなし
結果としてすぐに戻り
lockInterruptibly();がロックを取得しますが、対応する割り込み優先
待ちとウェイクアップ
に必要な条件条件= lock.newCondition();ロックオブジェクトの.condition.awaitは()
条件条件= lock.newCondition()を必要とするロックオブジェクト.conditionを。 .signal()
ReentrantLockの(真の)
公正ロック、我々が取得するために並ぶロック
ReadWriteLockの書き込みロック
別々の読み取りと書き込みロックを
相互に排他的で読み取ることがない:読み取りとの間には障害物
書き込みは相互に排他的:読み取り、書き込みをブロックされ、書き込みがブロックされます読み取り
、書き込み、相互に排他的:書き込みがブロックされて
読んで操作を読み書きロックが有効性を最大化し、システムのパフォーマンスを向上させることができ、書き込み動作時よりもはるかに大きいです。
ミューテックスロックやスピン:ミューテックスロックが詰まり待たなければならない、悲観的であり、スピンロックは、高効率の無限ループに注意を払うには、符号ロックループ監視を待たない楽観的ロックです。
間違ったロック
整数は、スレッドセーフになりますロックオブジェクト型は、整数は、同じオブジェクトに属し、それは不安につながる、それ私は++実際に新しいオブジェクトを作成していることが
何のロック機構CASない
、スレッドセーフAutomicInteger(原子タイプ) CASが使用ロックされていない、ロックイン技術
の比較およびスワップ:比較即ち再び切り替え
三つのパラメータ(V、E、N)を。V:(メインメモリ)が更新される変数のニーズを表し; E:期待値(ローカル・メモリ)、N新しい値。ときV = E説明は別のスレッドを裏返しすることはない、新しい価値Vの値を設定し、もしV = E、メインメモリリフレッシュサイクルの比較(スピンロックが)!
欠点:のようなABAの問題、 Bの値は、その後、戻って、それが間違っは変更されず、Javaの原子と契約アプリケーションクラスは、それがバージョンの制御変数値(タイムスタンプ)によって確保することができ、マークAtomicStampedReferenceを提供しますCASは正しいです。注無限ループ
ロックフリーの配列
AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray(使用ビューAPI)
変数もアトミック操作楽しむことができるようにする
AtomicIntergerFieldUpdaterを:
パブリッククラスAtomicIntegerFieldUpdaterDemo {
パブリック静的クラスCanditate {
int型ID。
揮発性のint型のスコア。
}
公共の最終静的AtomicIntegerFieldUpdater <Canditate> scoreUpdater = AtomicIntegerFieldUpdater.newUpdater(Canditate.class、 "スコア");
//チェックすると正常に動作させるアップデータ
のpublic staticのAtomicInteger allScore =新しいのAtomicInteger( 0);
パブリック静的無効メイン(文字列[] args){
最終CanditateのSTU =新しいCanditate()。
スレッド[] tは=新しいスレッド[10000];
以下のために(INT iが= 0; I <10000; I ++){
T [I] =新しいスレッド(){
@Override
公共ボイドラン(){
IF(Math.random()> 0.4){
scoreUpdater.incrementAndGet(STU)。
allScore.incrementAndGet();
}
}
}。
T [I] .start();
}
{(; I <10000 I ++ iが0 = INT)のため
のSystem.out.println( "スコア=" + stu.score)。
System.out.println( "allScore =" + allScore)。
}
}
}
注
アップデータは、それが目に見える範囲であることを、変数を変更することができます。アップデータの反射は、この変数を使用して得られたので。変数が表示されていない場合、エラーが発生しました。スコアは、正確な読み取りを確保するために、変数ではないでしょうプライベートとして、それがオブジェクトインスタンスによって揮発性CAS直接行動オフセット割り当ての種類によるものでなければならず、そのため、静的フィールドをサポートしていません宣言した
ロック最適化し
、保存を小さなロックホールド時間を
同期するためにのみ必要な
ことにより、並行システムの能力強化、ロックを減らす紛争のヘルプの可能性を
ロックを粗大化を
し、逆を考えて、ロック保持時間を短縮するには、すべてのロックは、ペア統合ロックで動作していましたこれにより、ロック用の同期要求の数を減らす最初の要求、。ロックは、資源の無駄を要求していきますので。:など(特に、ロックの保持時間を粗大化または減少ロックを使用状況に応じて選択される)
{公共ボイドdemoMethod()
{同期(ロック)
// STHを行う。
}
}
//他の
同期(ロック){
/ / STHを行う。
}
}
に
公共ボイドdemoMethod(){
同期(ロック){
STHは//行う。
//他
}
}
ロックの粒度の減少
コンセプト:これロックの競合を削減する、ロックオブジェクトを狭くする可能性を。そして、並行システムの能力向上させるために
、このようなConcurrentHashMapのように:最初に新しいエントリを追加する必要があり、全体ではなく、HashMapのロックが、ハッシュコードのエントリを取得するには、テイク・セグメントに応じて保存され、その後、セグメントをロックする必要があり、プット()操作を完了する。マルチスレッド環境では、複数のスレッドが同時に置く場合()操作は、限り、追加されたエントリのようにスレッドが真に平行とすることができる,,同じセグメント内に格納されていません。同時に、デフォルトのセグメント16、及び従って、幸運に許容される挿入糸16は、大幅にそのスループットを提供します。
問題:システムがグローバルロックを取得する必要があり、お互いに多くのリソースを消費するような場合には:サイズ()メソッド、あなたがのすべてのセグメント上のすべてのロックを取得する必要があり
、グローバルな情報を取得するだけで同様のサイズで()メソッドの呼び出しを頻繁にではない、それは種の本当の意味での粒子サイズを小さくするために、メソッドのスループットを向上させるシステム。
Java仮想マシンがロック最適化された
ロックバイアス
核となるアイデアを:スレッドが再びロックを要求する場合、スレッドは、ロックを取得するには、ロックはバイアスモードを入力する場合は、任意の同期操作は必要ありません。
用途:同じロック要求同じスレッド。
短所:より強いロック機会のための競争、効果がありません。各要求が異なるスレッドが同じロックを要求しているので、ロックが失敗する傾向があるので、偏ったロックが有効になっていないではないとして
使用する:Java仮想マシンのパラメータ-XX:+ UseBiasedLockingはロックバイアスオンにすることができ
、軽量ロックの
施錠をバイアスするとき失敗は、仮想マシンがすぐにハングアップしませんが、軽量ロックの使用を最適化する手段が、それはスレッドのリリースを決定するためのロックスタックを保持する雌ねじを指し示すポインタとして単に被験者の頭部だホールドオブジェクトロック。あなたは軽量ロックが成功した場合は、それがスムーズにクリティカル領域を入力することができます。それが失敗した場合、ロックに他のスレッドのための競争を表し、現在のスレッドのロック要求はヘビー級ロック拡大する
スピンロックを
オペレーティング・システム・レベルでのスレッドのハングを避けるために、ロック膨張後、実際の仮想マシンを、仮想マシンは、自己を使用します。スピンロック。現在のスレッドによるロックの取得を一時的にできないが、ロックをするとき、未知得られます。発疹スレッドがハングした場合、それがpyrrhic操作であってもよいです。したがって、システムは、賭けを行います:それは近い将来に想定します、スレッドがロックを取得することができます。あなたがロックを取得することができますのであれば、それはロックを取得できない場合限り成功し、クリティカルセクションを入力して、スレッドが真に運用となり、いくつかのサイクルの後、いくつかの空のサイクル(スピンの意味)を行うには、現在のスレッドの仮想機会を聞かせてシステムレベルのハング。
ロックが解消
時に、Java仮想マシンのJITコンパイラを完全にロックの最適化を実行しているコンテキストをスキャンすることによって、共有リソースの競合を削除するには、noロックはあり得ません。これは、ロックが無意味を要求し、時間を節約することができます。(JDK APIは、競争のロックが発生することはありません使用できます)
キーテクノロジー:エスケープ分析は、特定の変数が一定の範囲をエスケープするかどうかを観察することで
、エスケープ分析を開くには、+ DoEscapeAnalysisパラメータ:-XXを使用し、-serverモードで。
使用-XX:EliminateLocksパラメータを排除ロックを開くことができます。
同期ヘビー、軽量ロック制御不能と制御、柔軟性の高い、多用途:同期とロックの間の差。
同期と揮発性の違い
可視性とアトミックメモリ操作を保証するために同期
揮発性メモリのみの可視性を保証することができ
、揮発性を、ロックに同期、それはスレッドブロックすることはありません以上の軽量化は必要ありません
揮発性変数は、コンパイラの最適化をラベル付けされていませんが可変フラグが最適化コンパイラ(例えば、コンパイラの最適化をソート落胆)同期させることができる
揮発性改質変数であり、変数にのみ使用することができ、及び方法改質剤は、ブロックまたは同期化され
、本質的に揮発性の変数に電流JVMに指示レジスタの値は、メインメモリでの使用は、読み込みを開始する前に、可視性を達成することができ、不確実です。N + 1、N ++およびnの他の操作は=、揮発性のキーワードは失敗しますが、同期スレッド同期効果と同じように再生することはできません。