同期ロックとは何ですか?ロックは実際にはオブジェクトであり、どのオブジェクトでも使用できます。Java のすべてのオブジェクトはロックです。言い換えれば、Java のすべてのオブジェクトはロックになることができます。
今回は主に同期ロックのアップグレードのルーチンについて話します
synchronized
これは 4 つの段階を経ます: ロックなし状態、偏ったロック、軽量ロック、重みレベル ロック は、リソース消費量が最も少なくパフォーマンスが最も高いものから、リソース消費量が最も多くパフォーマンスが最も低いものまで順序付けされます。
まず、これらのステータス ロックがロックと呼ばれる理由と、その相互排他原則が何であるかを見てみましょう。
スレッドが 同期コード ブロック に到達し、ロック オブジェクトを取得しようとすると、オブジェクト内の MarkWord
をチェックします。スレッド ID、ここに ID がない場合は、独自の ID を保存してロックを取得します。存在する場合は、それが現在のスレッドであるかどうかを確認します。そうでない場合は、CAS がそのスレッドを変更しようとします。存在する場合は、ロック リソースが取得されています。
CAS が変更しようとするロジックの詳細な説明は次のとおりです。これは、バイアスされたロックを保持しているスレッドのステータスをチェックします。まず は、現在の JVM のすべての生き残ったスレッド を走査します。 がバイアスされたスレッド を見つけることができた場合、それはバイアスされたスレッド がまだ生きていることを意味します。 現時点でチェックされているスレッドは、同期されたコード ブロック内のコード を実行していますか? そうであれば、軽量ロックにアップグレードされ、CAS ロックの競合が継続されます。したがって、バイアスされたロックを追加した後は、1 つのスレッドのみがロックを取得し、同期されたコード ブロック内のコードを同時に実行できます。
軽量ロックオブジェクト ヘッダーのMarkWord の
Lock Record ポインターが現在のスレッドの仮想マシン スタックを指しているかどうかを確認します。 「はい」の場合は、ロックを使用してビジネスを実行します。そうでない場合は、CAS を実行して変更を試みます。変更が数回失敗した場合は、重量ロックにアップグレードします。
MarkWord で指定されている
ObjectMonitor を確認し、所有者が現在のスレッドであるかどうかを確認します (そうでない場合)。 、
ObjectMonitor の
EntryList に Queue をスローし、スレッドを一時停止して、起動されるのを待ちます。
新しい新しいオブジェクトは一時的に ロックフリー状態です 。バイアス ロックはデフォルトで遅延されるため、JVM の起動の最初の 4 秒間はバイアス ロックは発生しませんが、バイアス ロックの遅延設定がオフになっている場合は、匿名のバイアス ロックが新しいオブジェクトに追加されます。つまり、このオブジェクトはバイアス ロックを追加するスレッドを見つけようとしていますが、見つけることができません。これを匿名バイアスと呼びます。保存されるスレッドIDは0000の羅列であり、アドレス情報は一切ありません。
次の構成により、バイアスされたロック遅延をオフにすることができます。//关闭偏向锁延迟的指令 -XX:BiasedLockingStartuoDelay=0
このロック リソースを取得しようとすると、この時点で正常に取得され、偏ったロックになります。 、バイアスされたロック ストレージ スレッド ID。 バイアスされたロックがアップグレードされると、
バイアスされたロックの取り消しがトリガーされます。バイアスされたロックの取り消しは、安全なポイントまで待つ必要があります。 GC、バイアス ロックの取り消しのコストが高すぎるため、デフォルトでは、バイアス ロックの遅延が最初に実行されます。複数のスレッドが直接競合している場合、バイアス ロックはスキップされ、直接軽量ロックになります。 バイアスロック解除のプロセスを詳しく説明しますが、なぜコストがかかるのでしょうか?スレッドがバイアスされたロックを取得すると、ロック オブジェクト ヘッダーの Mark Work 内のスレッド ID がそれ自身を指します。別のスレッドがロックをめぐって競合し、ロックがアップグレードされると、
前に偏ったロックを取得したスレッドを一時停止します前に、ワークマークでスレッドID
をクリアし、軽量ロックを追加しますその後、一時停止したロックを復元しますスレッドは の実行を継続します。スレッドが一時停止されるため、ロック エスカレーションを実行する前に安全なポイントまで待機するのはこのためです。 #一般的な安全上のポイント: #GC 実行時
#メソッドが返される前
##軽量ロック
にアップグレードされます。軽量ロックの効果は、
CASが取得を試行することに基づいています。ロック リソースが使用されます。今回のスピン数は、最後の CAS の成功または失敗と費やされた時間に基づいて決定されます。
ヘビーウェイト ロックヘビーウェイト ロックに到達した場合は、何も言うことはありません。スレッドがロックを保持している場合、他の ロックを取得したい人はハングアップして待機します。ロックを解除すると、順番に目覚めます。 ロックの粗密化とロックの削除
ロックの粗密化/ロックの拡張ロックの拡張は、Java ファイルのコンパイル時に JIT が行うのに役立つ最適化です。買収とリリース。例えば:### 锁消除则是在一个加锁的同步代码块中,没有任何共享资源,也不存在锁竞争的情况,JIT编译时,就直接将锁的指令优化掉。 比如while(){
synchronized(){
// 多次的获取和释放,成本太高,会被优化为下面这种
}
}
synchronized(){
while(){
// 拿到锁后执行循环,只加锁和释放一次
}
}
锁消除
synchronized(){
int a = 1;
a++;
//操作局部变量的逻辑
}
以上がJava の同期ロックのアップグレード プロセスは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。