ソースコード解析へのエントリから同期

マイクロチャンネル公共数: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であります

おすすめ

転載: juejin.im/post/5df2666bf265da33f63f5015