ホームページ >Java >&#&チュートリアル >Javaキーワード同期原理とロック状態の分析例

Javaキーワード同期原理とロック状態の分析例

王林
王林転載
2023-05-11 15:25:06763ブラウズ

1. Java におけるロックの概念

  • スピン ロック: スレッドがロックを取得するときに、そのロックが他のスレッドによって取得されている場合、スレッドは待機することを意味します。ループ内で、ロックが正常に取得できるかどうかを継続的に判断し、ロックが取得されるまでループは終了しません。

  • 楽観的ロック: 競合がないことを前提として、データを変更する際に以前に取得したデータと不整合が見つかった場合、最新のデータを読み込み、変更を再試行します。

  • 悲観的ロック: 同時実行性の競合が発生することを想定し、データ関連のすべての操作を同期し、データが読み取られた時点からロックを開始します。

  • 排他ロック (書き込み): リソースに書き込みロックを追加します。スレッドはリソースを変更できますが、他のスレッドはリソースを再度ロックすることはできません (単一書き込み)。

  • 共有ロック (読み取り): リソースに読み取りロックを追加すると、読み取りのみ可能ですが変更はできません。他のスレッドは読み取りロックのみを追加でき、書き込みロックを追加できません (複数の場合) )。単なるセマフォ(手腕信号)と考えてください。

  • リエントラント ロックと非リエントラント ロック: スレッドはロックを取得した後、同じロックによって同期されている他のコードに自由に入力できます。

  • 公平なロックと不公平なロック: ロックを争う順序は、先着順であれば公平です。つまり、ロックを取得する順序とロックを取得する順序が同じであることが保証されていれば、それは公正なロックです。

2. 同期キーワード同期機能

機能: リエントラント、排他的、悲観的ロック。

ロック関連の最適化:

  • ロックの削除: ロックの削除を有効にするパラメーターは -XX: DoEscapeAnalysis-XX:ロックを排除します。

  • ロックの粗密化: JDK はロックの粗密化を最適化していますが、コード レベルから最適化することもできます。

1. ロックの削除の例

/**
 * 锁消除示例,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");
	}
}

2. ロックの粗密化の例

/**
 * 锁粗化示例
 * @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++;
		}
	}
}

注: ロックの削除とロックの粗密化の違いは、ロックの削除です。単一スレッドの追加とロック解除を繰り返すように最適化されており、最終的にはロックが存在しません。ロックの粗大化は単一スレッドだけでなく、最終的にはロックが発生します。

3. 同期キーワードの原則

1. Mark Word について

まず、ヒープ内のオブジェクトは、オブジェクト ヘッダー、インスタンス データ、およびアライメント パディングで構成されます。

オブジェクト ヘッダーには 2 つの情報部分が含まれています。最初の部分は、ハッシュ コード、GC 生成経過時間、ロック ステータス フラグ、スレッドが保持するロック、バイアスなど、オブジェクト自体の実行時データを保存するために使用されます。ロックIDなど。データのこの部分は正式には「マークワード」と呼ばれます。

オブジェクト ヘッダーの他の部分は、クラス メタデータへのオブジェクトのポインタであるタイプ ポインタです。仮想マシンはこのポインタを使用して、オブジェクトがどのクラスのインスタンスであるかを判断します。

synchronized によって実装されるロックは、オブジェクト ヘッダーの「Mark Word」を変更することで実現されます。

「Mard Word」は、32 ビットおよび 64 ビットの仮想マシンではそれぞれ 32 ビットと 64 ビットです (圧縮ポインターはオンになっていません)。 32 ビット仮想マシン "Mark Word" は次のとおりです:

Javaキーワード同期原理とロック状態の分析例

2. ロック ステータスの変更

(1) ロックなし→ 軽量ロック
ロックフリーが軽量ロックになると、複数のスレッドがオブジェクトのオブジェクトヘッダーのロックフリーステータスマークワードコンテンツを読み取り、

cas 操作を実行してそれを変更します。は、ロックフリーのステータス マーク ワードの内容です。新しい値は、軽量ロック ステータス マークのワードの内容です。変更が成功した場合、ロック レコード アドレスは、スレッドの ロック レコードを指します。ロックの取得に成功しました。

デモのプロセスは次のとおりです:

Javaキーワード同期原理とロック状態の分析例##(2) 軽量ロック→ 重量ロック

スレッドが取得に失敗したため、ロックが成功しました スピンします。長時間のスピンは CPU リソースを消費するため、一定回数スピンすると、ロックは軽量ロックから重量ロックにアップグレードされます。

ヘビーウェイト ロックは、entryList (ロック プール)、owner (ロック ホルダー)、waitSet (待機セット) などを含むオブジェクト モニターを通じて実装されます。

ヘビーウェイト ロックにアップグレードする場合、オブジェクト ヘッダー マーク ワードの内容は、オブジェクト モニターを指すモニター アドレス (オブジェクト モニター アドレス) になります。

デモ プロセスは次のとおりです:

Javaキーワード同期原理とロック状態の分析例注: ロックの取得に失敗したスレッドは、entryList (ロック プール) に入ります。 wait メソッドを使用すると、スレッドは waitSet(Wait set) に入り、waitSet 内のスレッドは目覚めた後、entryList に再度入ります。

(3) バイアスロックについて

シングルスレッドでロック後のロックが解除されない

いわゆるバイアスとは偏心のことで、シングルスレッドロック後はロックが解除されなくなります。ロック→業務処理→ロック解除→ロック操作プロセスを削減します。

JDK6 以降、バイアスされたロックの最適化はデフォルトで有効になっています。バイアスされたロックは、JVM パラメータ

-XX:-UseBiasedLocking

を通じて無効にできます。バイアスされたロックが有効な場合は、1 つのみですスレッドがロックを取得し、バイアス ロックを取得できます。 バイアスロックマークワードについて、内容は以下の通りです。

バイアス マークは、最初は役に立ちますが、競合が発生すると役に立たなくなります。

バイアスされたロックの本質は、ロックフリーであることです。ロックをめぐって競合するマルチスレッドがない場合、JVM はそれを単一のスレッドとみなし、同期は必要ありません。

注: JVM の作業を軽減するために、同期は JVM の下部で多くの操作によって実装されます。競合がない場合は、同期操作を実行する必要はありません。

(4) 完全なロック アップグレード プロセス

バイアス ロックがオンになっていない場合、まずロックなし状態が軽量ロックにアップグレードされ、軽量ロックが次の状態にアップグレードされます。ある程度選択すると重量級になります。

バイアスされたロックがオンになっている場合、次の 2 つの状況が考えられます。

  • ロックが占有されていない場合は、ロックなしにアップグレードされ、その後、ロックが占有されません。軽量ロックにアップグレードされる ロックは軽量ロックから重量ロックにアップグレードされます。

  • ロックが占有されると、軽量ロックにアップグレードされ、その後、軽量ロックから重量ロックにアップグレードされます。

Javaキーワード同期原理とロック状態の分析例

以上がJavaキーワード同期原理とロック状態の分析例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。