Java同期とは

WBOY
リリース: 2023-05-14 08:28:05
転載
1753 人が閲覧しました

Synchronized とは

Java 読者の皆さん、あなたは synchronized キーワードに馴染みがあるでしょう。これはさまざまなミドルウェア ソース コードや JDK ソース コードで見られます。synchronized に詳しくない読者にとっては、 synchronized によってスレッドの安全性が確保されることを理解して、synchronized キーワードを使用する必要があります。

  • 呼び出し先: ミューテックス ロック (同時に実行できるのは 1 つのスレッドのみで、他のスレッドは待機します)

  • 別名: 悲観的ロック (同時に実行できるのは 1 つのスレッドだけであり、他のスレッドは待機します)

  • JVM 仮想マシンが実装に役立ちます。開発者は synchronized キーワードを使用するだけで済みます。

  • これを使用する場合は、オブジェクトをロック ミューテックスとして使用する必要があります。

  • コードの原子性と可視性を確保できます。 (クリティカルセクション)。

Synchronized キーワードをバイトコード レベルから分析する

ケースから始めるのが最も適切です。

class Demo1{
    // 互斥对象
    static Object object = new Object();
    // 竞争条件
    static int cout = 0;
    public static void main(String[] args) {
        // 互斥
        synchronized(object){
            // 以下是临界区
            cout++;
            System.out.println("synchronized");
        }
    }
}
ログイン後にコピー

Java コードだけからは何もわかりません。Java プログラムはバイトコード ファイルにコンパイルされるため、バイトコードを解析します

定数プール:
#1 = Methodref #7.#26 // java/lang/Object."":()V
#2 = Fieldref #8.# 27 // Demo1.object:Ljava/lang/Object;
#3 = Fieldref #8.#28 // Demo1.cout:I
#4 = Fieldref #29.#30 // java/lang/ System.out:Ljava/io/PrintStream;
#5 = String #31 // synchronized
#6 = Methodref #32.#33 // java/io/PrintStream.println:(Ljava/lang/String ;)V
#7 = クラス #34 // java/lang/Object
#8 = クラス #35 // Demo1
#9 = Utf8 object
#10 = U tf8 Ljava/lang/オブジェクト;
#11 = Utf8 cout
#12 = Utf8 I
#13 = Utf8
#14 = Utf8 ()V
#15 = Utf8コード
#16 = Utf8 LineNumberTable
#17 = Utf8 main
#18 = Utf8 ([Ljava/lang/String;)V
#19 = Utf8 StackMapTable
#20 = クラス#36 // " [Ljava/lang/String;"
#21 = クラス #34 // java/lang/Object
#22 = クラス #37 // java/lang/Throwable
#23 = Utf8 ;
#24 = Utf8 SourceFile
#25 = Utf8 Demo1.java
#26 = NameAndType #13:#14 // "":()V
#27 = NameAndType #9:#10 // object:Ljava/lang/Object;
#28 = NameAndType #11:#12 // cout:I
#29 = クラス #38 // java/lang/System## ##30 = nameandtype#39:#40 // out:ljava/io/printstream;
#31 = utf8同期
#32 =クラス#41 // java/io/printStream
# 33 = NameAndType #42:#43 // println:(Ljava/lang/String;)V
#34 = Utf8 java/lang/Object
#35 = Utf8 Demo1
#36 = Utf8 [Ljava/lang /String;
#37 = Utf8 java/lang/Throwable
#38 = Utf8 java/lang/System
#39 = Utf8 out
#40 = Utf8 Ljava/io/PrintStream;
#41 = Utf8 java/io/PrintStream
#42 = Utf8 println
#43 = Utf8 (Ljava/lang/String;)V
0: getstatic #2 //从2号常量池中拿到静态变量,压入操作数栈中
3: dup // 操作数栈顶の对象赋值一份
4: ASTORE_1 // 運用番号スタックのデータをローカル変数テーブル No. 1 に保存し、
を使用します。 5: Monitorenter // 解放ロックでロックを開き、同期化されたバイトコード層でもあります。 implement
6: getstatic #3 // 定数プールNo.2からstatic変数を取得し、オペランドスタックにプッシュ
9: iconst_1 iconst_1 // 定数1をオペランドスタックにプッシュ
10: iadd 10: iadd // 消費 2つのオペランドスタックのデータを加算してスタックの先頭にプッシュします
11: putstatic #3 // オペランドスタックの先頭の変数を定数プールNo.に代入します。 3
14: getstatic #4 // 定数プール4番のオブジェクトをオペランドスタックにプッシュ
17: ldc #5 // 定数プール5のシンボルを解析し、文字列定数「synchronized」を取得
19: invokevirtual #6 // println関数実行、演算スタック2個消費
22: ALOAD_1 // ローカル変数テーブル1のデータを演算番号スタックに押し込む
23: Monitorexit // 終了相互ロックの同期実装のバイト コード レベルでもあります。
24: goto 32 // 32 行目にジャンプします。
27:Monitorexit命令で使用されるスタックの上部からAstore_2
29:Monitorexit //例外があるかもしれませんが、ロックをリリースする必要があります。
30: aload_2 ‐ 32 にスローされる例外を受け取るには、 // Function returns


上記はバイトコードの完全な説明です。実際には非常に簡単です。最後に、同期キーワードは、monitorenter およびmonitorexit バイトコード命令に解析され、これら 2 つのバイトコード命令を実行するたびに、mutex オブジェクトが、monitorenter およびmonitorexit バイトコード命令で使用できるようにオペランド スタックにプッシュされます。

したがって、次の記事では、Hotspot ソース コードに移動して、monitorenter およびmonitorexit バイトコード命令の詳細なプロセスを解析します。

Synchronized ロックと ReentrantLock の違い

これは非常に一般的な面接の質問であり、面接でも非常に頻繁に尋ねられます

類似点:

両方はミューテックス ロックの実装です。

違い:

Synchronized は JVM の内部実装に基づいており、ReentrantLock は Java レベルで実装されます (ただし、コアReentrantLock のコードは引き続き C コードを呼び出します)。
  • Synchronized は 1.6 以降で最適化されています。ロックにはいくつかの異なるレベルがあり、スレッドの競合の激しさに応じてロックの強度が増加します (一般にロック アップグレードと呼ばれます)。はシナリオにより適していますが、ReentrantLock はロック強度の選択が少し厳密です。
  • ReentrantLock はロック強度の選択が若干厳格ですが、公平なロックと不公平なロックのどちらかを選択できますが、Synchronized は不公平なロックのみを選択できます
  • ReentrantLock の条件付き待機キューは、高度にカスタマイズされた複数のキューを作成できます。 Synchronized の最後にはキューが 1 つだけあります。
  • ReentrantLock では、ユーザーが手動でロックを開いて手動でロックを解放する必要があります。 Synchronized キーワードの最下層は、バイトコード
  • によって自動的に実装されます。

以上がJava同期とはの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:yisu.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート