マイクロチャンネル公共数:Javaの患者
シンクロナイズド
同期のプロフィール
synchronizedキーワードは、Javaで、Javaは、並行プログラミングの存在下でアトミック、視認性と秩序の問題を解決するために言語である並列処理と関連するキーワードの範囲を提供し、我々は今日、同期簡単な外観を取る必要があります。
どのようにロック?
package com.zero.day3;
/**
* @Description: synchronized
* @Author: Zero
* @Date: 2019/12/10
*/
public class SynchronizedDemo1 {
// 同步方法
public synchronized void wc1 () {
System.out.println("我在上厕所1");
}
// 同步方法 (静态)
public static void wc2 () {
synchronized (SynchronizedDemo1.class) {
System.out.println("我在上厕所2");
}
}
// 同步代码块
public void wc3 () {
synchronized (this) {
System.out.println("我在上厕所3");
}
}
}
复制代码
上記の3つの簡単な方法は、一般的な同期方法に追加された場合:ロックが同期キーワードは、オブジェクトの現在のインスタンスであることであり、同時に、それぞれの方法は、単一のスレッド、使用中に同じ時間だけ一人でトイレによってアクセスすることができます。静的同期方法:ロック(現在のクラスのオブジェクトがクラスであるので、操作は、静的メソッドをオブジェクトを有していなくてもよい場合、静的メソッドは、オブジェクトの前に実行されるため)現在のクラスは、ブロック同期メソッドオブジェクトのクラスである:ロックオブジェクトは、括弧で
同期の実装原理
私たちは今、上記の方法の操作を逆コンパイル
LINENUMBER 8 L0
ALOAD 0
INVOKESPECIAL java/lang/Object.<init> ()V
RETURN
L1
LOCALVARIABLE this Lcom/zero/day3/SynchronizedDemo1; L0 L1 0
MAXSTACK = 1
MAXLOCALS = 1
// access flags 0x21
public synchronized wc1()V
L0
LINENUMBER 15 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\u6211\u5728\u4e0a\u5395\u62401"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L1
LINENUMBER 16 L1
RETURN
L2
LOCALVARIABLE this Lcom/zero/day3/SynchronizedDemo1; L0 L2 0
MAXSTACK = 2
MAXLOCALS = 1
// access flags 0x9
public static wc2()V
TRYCATCHBLOCK L0 L1 L2 null
TRYCATCHBLOCK L2 L3 L2 null
L4
LINENUMBER 21 L4
LDC Lcom/zero/day3/SynchronizedDemo1;.class
DUP
ASTORE 0
MONITORENTER
L0
LINENUMBER 22 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\u6211\u5728\u4e0a\u5395\u62402"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L5
LINENUMBER 23 L5
ALOAD 0
MONITOREXIT
L1
GOTO L6
L2
FRAME FULL [java/lang/Object] [java/lang/Throwable]
ASTORE 1
ALOAD 0
MONITOREXIT
L3
ALOAD 1
ATHROW
L6
LINENUMBER 24 L6
FRAME CHOP 1
RETURN
MAXSTACK = 2
MAXLOCALS = 2
// access flags 0x1
public wc3()V
TRYCATCHBLOCK L0 L1 L2 null
TRYCATCHBLOCK L2 L3 L2 null
L4
LINENUMBER 29 L4
ALOAD 0
DUP
ASTORE 1
MONITORENTER
L0
LINENUMBER 30 L0
GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
LDC "\u6211\u5728\u4e0a\u5395\u62403"
INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
L5
LINENUMBER 31 L5
ALOAD 1
MONITOREXIT
L1
GOTO L6
L2
FRAME FULL [com/zero/day3/SynchronizedDemo1 java/lang/Object] [java/lang/Throwable]
ASTORE 2
ALOAD 1
MONITOREXIT
L3
ALOAD 2
ATHROW
L6
LINENUMBER 32 L6
FRAME CHOP 1
RETURN
L7
LOCALVARIABLE this Lcom/zero/day3/SynchronizedDemo1; L4 L7 0
MAXSTACK = 2
MAXLOCALS = 3
}
复制代码
私たちは、実際にMONITOREXIT二つの言葉でMONITORENTERを見つけることができます慎重に見て、それから、私は、このプロセスは比較的単純で、粗言語やったものとのあなたに来ます。この時間は、それはメソッドを呼び出すために、同時に3つのスレッドスレッド1、スレッド2、Thread3があり、コードは確かにあなたによって共有されている場合、このメソッド関数は、このコードを実行するために、スレッド1がロックされていないとき、そして、あなたはまた、半分のスレッド2を実行することができますもちろん、Thread3を実行するために、も行うことができます。この方法に加えてロック機能は、このコードコンパイラの後に同じでない場合は、ああ、スレッド1は、この方法を実行するためにCPUの実行をつかむためにする場合、2つの命令を生成します、このMONITORENTER時間を満たし、この強力なああに!これは、別のスレッドは、我々はすべて知っているスレッドがwaitメソッドを呼び出した後、待機状態に入ること、誰もが自然に、彼らに露骨このロック方法の後に実行され、独自のスレッド1に、この時間を節約することはできませんwaitメソッドを呼び出しましたMONITOREXITコマンドでは、この時間スレッドがまだ待っていますか?スレッドが待機中であるときに行うためにどのように、我々はすべて知っているののnotifyAllメソッドは、他の全てのスレッドをウェイクアップするために呼び出されます、すべてのスレッドが復活し、この時間は続行します。
エピローグ
それは公共のマイクロチャンネル番号に関係するか、または私達のJavaを勉強するために私を追加するように小扁は、Javaコーダー、アマチュア書き込み記事、今やメインマイクロチャネル公共番号「のJava患者、」Iであります