ホームページ >Java >&#&チュートリアル >Javaキーワード同期原理とロック状態の分析例
スピン ロック: スレッドがロックを取得するときに、そのロックが他のスレッドによって取得されている場合、スレッドは待機することを意味します。ループ内で、ロックが正常に取得できるかどうかを継続的に判断し、ロックが取得されるまでループは終了しません。
楽観的ロック: 競合がないことを前提として、データを変更する際に以前に取得したデータと不整合が見つかった場合、最新のデータを読み込み、変更を再試行します。
悲観的ロック: 同時実行性の競合が発生することを想定し、データ関連のすべての操作を同期し、データが読み取られた時点からロックを開始します。
排他ロック (書き込み): リソースに書き込みロックを追加します。スレッドはリソースを変更できますが、他のスレッドはリソースを再度ロックすることはできません (単一書き込み)。
共有ロック (読み取り): リソースに読み取りロックを追加すると、読み取りのみ可能ですが変更はできません。他のスレッドは読み取りロックのみを追加でき、書き込みロックを追加できません (複数の場合) )。単なるセマフォ(手腕信号)と考えてください。
リエントラント ロックと非リエントラント ロック: スレッドはロックを取得した後、同じロックによって同期されている他のコードに自由に入力できます。
公平なロックと不公平なロック: ロックを争う順序は、先着順であれば公平です。つまり、ロックを取得する順序とロックを取得する順序が同じであることが保証されていれば、それは公正なロックです。
機能: リエントラント、排他的、悲観的ロック。
ロック関連の最適化:
ロックの削除: ロックの削除を有効にするパラメーターは -XX: DoEscapeAnalysis
、-XX:ロックを排除します。
/** * 锁消除示例,JIT即时编译,进行了锁消除 * @author 刘亚楼 * @date 2020/1/16 */ public class LockEliminationExample { /** * StringBuilder线程不安全,StringBuffer用了synchronized关键字,是线程安全的 * 针对下面这种单线程加锁、解锁操作,JIT会进行优化,进行锁消除 */ public static void eliminateLock() { StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); stringBuffer.append("a"); stringBuffer.append("b"); stringBuffer.append("c"); } }
/** * 锁粗化示例 * @author 刘亚楼 * @date 2020/1/16 */ public class LockCoarseningExample { /** * 针对下面这种无意义的加锁操作,JIT会进行优化,对变量i的所有操作放到一个同步代码块里 */ public static void lockCoarsening() { int i = 0; synchronized (LockCoarseningExample.class) { i++; } synchronized (LockCoarseningExample.class) { i--; } synchronized (LockCoarseningExample.class) { i++; } synchronized (LockCoarseningExample.class) { i++; i--; i++; } } }
cas 操作を実行してそれを変更します。は、ロックフリーのステータス マーク ワードの内容です。新しい値は、軽量ロック ステータス マークのワードの内容です。変更が成功した場合、
ロック レコード アドレスは、スレッドの
ロック レコードを指します。ロックの取得に成功しました。
##(2) 軽量ロック→ 重量ロック
ヘビーウェイト ロックは、entryList (ロック プール)、owner (ロック ホルダー)、waitSet (待機セット) などを含むオブジェクト モニターを通じて実装されます。
ヘビーウェイト ロックにアップグレードする場合、オブジェクト ヘッダー マーク ワードの内容は、オブジェクト モニターを指すモニター アドレス (オブジェクト モニター アドレス) になります。
デモ プロセスは次のとおりです:
注: ロックの取得に失敗したスレッドは、entryList (ロック プール) に入ります。 wait メソッドを使用すると、スレッドは waitSet(Wait set) に入り、waitSet 内のスレッドは目覚めた後、entryList に再度入ります。
(3) バイアスロックについて
いわゆるバイアスとは偏心のことで、シングルスレッドロック後はロックが解除されなくなります。ロック→業務処理→ロック解除→ロック操作プロセスを削減します。
JDK6 以降、バイアスされたロックの最適化はデフォルトで有効になっています。バイアスされたロックは、JVM パラメータ
-XX:-UseBiasedLocking を通じて無効にできます。バイアスされたロックが有効な場合は、1 つのみですスレッドがロックを取得し、バイアス ロックを取得できます。 バイアスロックマークワードについて、内容は以下の通りです。
バイアス マークは、最初は役に立ちますが、競合が発生すると役に立たなくなります。
バイアスされたロックの本質は、ロックフリーであることです。ロックをめぐって競合するマルチスレッドがない場合、JVM はそれを単一のスレッドとみなし、同期は必要ありません。
注: JVM の作業を軽減するために、同期は JVM の下部で多くの操作によって実装されます。競合がない場合は、同期操作を実行する必要はありません。
バイアス ロックがオンになっていない場合、まずロックなし状態が軽量ロックにアップグレードされ、軽量ロックが次の状態にアップグレードされます。ある程度選択すると重量級になります。
バイアスされたロックがオンになっている場合、次の 2 つの状況が考えられます。
ロックが占有されていない場合は、ロックなしにアップグレードされ、その後、ロックが占有されません。軽量ロックにアップグレードされる ロックは軽量ロックから重量ロックにアップグレードされます。
ロックが占有されると、軽量ロックにアップグレードされ、その後、軽量ロックから重量ロックにアップグレードされます。
以上がJavaキーワード同期原理とロック状態の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。