ホームページ >Java >&#&チュートリアル >Java同期とは
Java 読者の皆さん、あなたは synchronized キーワードに馴染みがあるでしょう。これはさまざまなミドルウェア ソース コードや JDK ソース コードで見られます。synchronized に詳しくない読者にとっては、 synchronized によってスレッドの安全性が確保されることを理解して、synchronized キーワードを使用する必要があります。
呼び出し先: ミューテックス ロック (同時に実行できるのは 1 つのスレッドのみで、他のスレッドは待機します)
別名: 悲観的ロック (同時に実行できるのは 1 つのスレッドだけであり、他のスレッドは待機します)
JVM 仮想マシンが実装に役立ちます。開発者は 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 プログラムはバイトコード ファイルにコンパイルされるため、バイトコードを解析します
したがって、次の記事では、Hotspot ソース コードに移動して、monitorenter およびmonitorexit バイトコード命令の詳細なプロセスを解析します。 Synchronized ロックと ReentrantLock の違いこれは非常に一般的な面接の質問であり、面接でも非常に頻繁に尋ねられます類似点:両方はミューテックス ロックの実装です。違い: Synchronized は JVM の内部実装に基づいており、ReentrantLock は Java レベルで実装されます (ただし、コアReentrantLock のコードは引き続き C コードを呼び出します)。定数プール:
#1 = Methodref #7.#26 // java/lang/Object."5655bee0e910362c4b50f45afb3465e0
#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 // "7e51f00a783d7eb8f68358439dee7daf":()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 バイトコード命令で使用できるようにオペランド スタックにプッシュされます。
によって自動的に実装されます。
以上がJava同期とはの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。