Synchronized 수식 방법 과 코드 블록 이 밑 에 있 는 차이 점

16617 단어 자바 진격 의 길
글 목록
수식 코드 블록
인 스 턴 스 를 수식 하 는 방법수식 정태 방법
총화
수식 코드 블록
위의 예:
public class SyncCodeBlock {
    public int i;

    public void syncTask(){
        //     
        synchronized (this){
            i++;
        }
    }
}

자바 c 컴 파일 을 사용 하여 자바 p 로 바이트 코드 를 봅 니 다:

$javac SyncCodeBlock.java
$javap -v -c -s -l SyncCodeBlock.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SyncCodeBlock.class
  Last modified 2020-6-26; size 427 bytes
  MD5 checksum 46c58b50c71e6579e6e3d8b903ac2680
  Compiled from "SyncCodeBlock.java"
public class ThreadBasic.Synchronized.SyncCodeBlock
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #4.#18         // java/lang/Object."":()V
   #2 = Fieldref           #3.#19         // ThreadBasic/Synchronized/SyncCodeBlock.i:I
   #3 = Class              #20            // ThreadBasic/Synchronized/SyncCodeBlock
   #4 = Class              #21            // java/lang/Object
   #5 = Utf8               i
   #6 = Utf8               I
   #7 = Utf8               
   #8 = Utf8               ()V
   #9 = Utf8               Code
  #10 = Utf8               LineNumberTable
  #11 = Utf8               syncTask
  #12 = Utf8               StackMapTable
  #13 = Class              #20            // ThreadBasic/Synchronized/SyncCodeBlock
  #14 = Class              #21            // java/lang/Object
  #15 = Class              #22            // java/lang/Throwable
  #16 = Utf8               SourceFile
  #17 = Utf8               SyncCodeBlock.java
  #18 = NameAndType        #7:#8          // "":()V
  #19 = NameAndType        #5:#6          // i:I
  #20 = Utf8               ThreadBasic/Synchronized/SyncCodeBlock
  #21 = Utf8               java/lang/Object
  #22 = Utf8               java/lang/Throwable
{
  public int i;
    descriptor: I
    flags: ACC_PUBLIC

  public ThreadBasic.Synchronized.SyncCodeBlock();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return
      LineNumberTable:
        line 3: 0

  public void syncTask();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=3, locals=3, args_size=1
         0: aload_0
         1: dup
         2: astore_1
         3: monitorenter
         4: aload_0
         5: dup
         6: getfield      #2                  // Field i:I
         9: iconst_1
        10: iadd
        11: putfield      #2                  // Field i:I
        14: aload_1
        15: monitorexit
        16: goto          24
        19: astore_2
        20: aload_1
        21: monitorexit
        22: aload_2
        23: athrow
        24: return
      Exception table:
         from    to  target type
             4    16    19   any
            19    22    19   any
      LineNumberTable:
        line 9: 0
        line 10: 4
        line 11: 14
        line 12: 24
      StackMapTable: number_of_entries = 2
        frame_type = 255 /* full_frame */
          offset_delta = 19
          locals = [ class ThreadBasic/Synchronized/SyncCodeBlock, class java/lang/Object ]
          stack = [ class java/lang/Throwable ]
        frame_type = 250 /* chop */
          offset_delta = 4
}
SourceFile: "SyncCodeBlock.java"


JVM 은 입력,종료 대상 모니터(Monitor)를 통 해 코드 블록 에 대한 동기 화 를 실현 합 니 다.
수식 실례 방법
public class SyncInstance implements  Runnable{
        static int i = 0;

        public synchronized void increase() {
            i++;
        }

        @Override
        public void run() {
            for (int j = 0; j < 5; j++) {
                increase();
            }
        }

        public static void main(String[] args) throws InterruptedException {
            //new   
            Thread t1 = new Thread(new SyncInstance());
            //new   
            t1.start();
            //join  :    A  thread         thread.join()  
            t1.join();
        }
}


바이트 코드 보기:
$javac SyncInstance.java
$javap -v -c -s -l SyncInstance.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SyncInstance.class
  Last modified 2020-6-26; size 769 bytes
  MD5 checksum 4bc0bc765b64da5799760cf7a04b01cc
  Compiled from "SyncInstance.java"
public class ThreadBasic.Synchronized.SyncInstance implements java.lang.Runnable
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #10.#28        // java/lang/Object."":()V
   #2 = Fieldref           #5.#29         // ThreadBasic/Synchronized/SyncInstance.i:I
   #3 = Methodref          #5.#30         // ThreadBasic/Synchronized/SyncInstance.increase:()V
   #4 = Class              #31            // java/lang/Thread
   #5 = Class              #32            // ThreadBasic/Synchronized/SyncInstance
   #6 = Methodref          #5.#28         // ThreadBasic/Synchronized/SyncInstance."":()V
   #7 = Methodref          #4.#33         // java/lang/Thread."":(Ljava/lang/Runnable;)V
   #8 = Methodref          #4.#34         // java/lang/Thread.start:()V
   #9 = Methodref          #4.#35         // java/lang/Thread.join:()V
  #10 = Class              #36            // java/lang/Object
  #11 = Class              #37            // java/lang/Runnable
  #12 = Utf8               i
  #13 = Utf8               I
  #14 = Utf8               
  #15 = Utf8               ()V
  #16 = Utf8               Code
  #17 = Utf8               LineNumberTable
  #18 = Utf8               increase
  #19 = Utf8               run
  #20 = Utf8               StackMapTable
  #21 = Utf8               main
  #22 = Utf8               ([Ljava/lang/String;)V
  #23 = Utf8               Exceptions
  #24 = Class              #38            // java/lang/InterruptedException
  #25 = Utf8               
  #26 = Utf8               SourceFile
  #27 = Utf8               SyncInstance.java
  #28 = NameAndType        #14:#15        // "":()V
  #29 = NameAndType        #12:#13        // i:I
  #30 = NameAndType        #18:#15        // increase:()V
  #31 = Utf8               java/lang/Thread
  #32 = Utf8               ThreadBasic/Synchronized/SyncInstance
  #33 = NameAndType        #14:#39        // "":(Ljava/lang/Runnable;)V
  #34 = NameAndType        #40:#15        // start:()V
  #35 = NameAndType        #41:#15        // join:()V
  #36 = Utf8               java/lang/Object
  #37 = Utf8               java/lang/Runnable
  #38 = Utf8               java/lang/InterruptedException
  #39 = Utf8               (Ljava/lang/Runnable;)V
  #40 = Utf8               start
  #41 = Utf8               join
{
  static int i;
    descriptor: I
    flags: ACC_STATIC

  public ThreadBasic.Synchronized.SyncInstance();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return
      LineNumberTable:
        line 3: 0

  public synchronized void increase();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=1, args_size=1
         0: getstatic     #2                  // Field i:I
         3: iconst_1
         4: iadd
         5: putstatic     #2                  // Field i:I
         8: return
      LineNumberTable:
        line 7: 0
        line 8: 8

  public void run();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iload_1
         3: iconst_5
         4: if_icmpge     17
         7: aload_0
         8: invokevirtual #3                  // Method increase:()V
        11: iinc          1, 1
        14: goto          2
        17: return
      LineNumberTable:
        line 12: 0
        line 13: 7
        line 12: 11
        line 15: 17
      StackMapTable: number_of_entries = 2
        frame_type = 252 /* append */
          offset_delta = 2
          locals = [ int ]
        frame_type = 250 /* chop */
          offset_delta = 14

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=2, args_size=1
         0: new           #4                  // class java/lang/Thread
         3: dup
         4: new           #5                  // class ThreadBasic/Synchronized/SyncInstance
         7: dup
         8: invokespecial #6                  // Method "":()V
        11: invokespecial #7                  // Method java/lang/Thread."":(Ljava/lang/Runnable;)V
        14: astore_1
        15: aload_1
        16: invokevirtual #8                  // Method java/lang/Thread.start:()V
        19: aload_1
        20: invokevirtual #9                  // Method java/lang/Thread.join:()V
        23: return
      LineNumberTable:
        line 19: 0
        line 21: 15
        line 23: 19
        line 24: 23
    Exceptions:
      throws java.lang.InterruptedException

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_0
         1: putstatic     #2                  // Field i:I
         4: return
      LineNumberTable:
        line 4: 0
}
SourceFile: "SyncInstance.java"


synchronized 수식 의 인 스 턴 스 방법 은 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACCSYNCHRONIZED 표 지 는 이 방법 이 동기 화 방법 임 을 가리 키 며 JVM 은 이 ACC 를 통 해SYNCHRONIZED 방문 표 지 는 하나의 방법 이 동기 화 방법 인지 여 부 를 판별 하여 해당 하 는 동기 화 호출 을 수행 합 니 다.
수식 정적 방법
package ThreadBasic.Synchronized;

public class SynStatic implements Runnable {
    static int i = 0;

    public static synchronized void increase() {
        i++;
    }

    @Override
    public void run() {
        for (int j = 0; j < 5; j++) {
            increase();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        //new   
        Thread t1 = new Thread(new SynStatic());
        //new   
        t1.start();
        //join  :    A  thread         thread.join()  
        t1.join();
    }
}



바이트 코드 보기:
$javac SynStatic.java
$javap -c -v -s -l SynStatic.class
Classfile /Users/mac/IdeaProjects/multiThread/src/main/java/ThreadBasic/Synchronized/SynStatic.class
  Last modified 2020-6-26; size 762 bytes
  MD5 checksum f66c06958c4b1a7b9e84d47933cc6dda
  Compiled from "SynStatic.java"
public class ThreadBasic.Synchronized.SynStatic implements java.lang.Runnable
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
   #1 = Methodref          #10.#28        // java/lang/Object."":()V
   #2 = Fieldref           #5.#29         // ThreadBasic/Synchronized/SynStatic.i:I
   #3 = Methodref          #5.#30         // ThreadBasic/Synchronized/SynStatic.increase:()V
   #4 = Class              #31            // java/lang/Thread
   #5 = Class              #32            // ThreadBasic/Synchronized/SynStatic
   #6 = Methodref          #5.#28         // ThreadBasic/Synchronized/SynStatic."":()V
   #7 = Methodref          #4.#33         // java/lang/Thread."":(Ljava/lang/Runnable;)V
   #8 = Methodref          #4.#34         // java/lang/Thread.start:()V
   #9 = Methodref          #4.#35         // java/lang/Thread.join:()V
  #10 = Class              #36            // java/lang/Object
  #11 = Class              #37            // java/lang/Runnable
  #12 = Utf8               i
  #13 = Utf8               I
  #14 = Utf8               
  #15 = Utf8               ()V
  #16 = Utf8               Code
  #17 = Utf8               LineNumberTable
  #18 = Utf8               increase
  #19 = Utf8               run
  #20 = Utf8               StackMapTable
  #21 = Utf8               main
  #22 = Utf8               ([Ljava/lang/String;)V
  #23 = Utf8               Exceptions
  #24 = Class              #38            // java/lang/InterruptedException
  #25 = Utf8               
  #26 = Utf8               SourceFile
  #27 = Utf8               SynStatic.java
  #28 = NameAndType        #14:#15        // "":()V
  #29 = NameAndType        #12:#13        // i:I
  #30 = NameAndType        #18:#15        // increase:()V
  #31 = Utf8               java/lang/Thread
  #32 = Utf8               ThreadBasic/Synchronized/SynStatic
  #33 = NameAndType        #14:#39        // "":(Ljava/lang/Runnable;)V
  #34 = NameAndType        #40:#15        // start:()V
  #35 = NameAndType        #41:#15        // join:()V
  #36 = Utf8               java/lang/Object
  #37 = Utf8               java/lang/Runnable
  #38 = Utf8               java/lang/InterruptedException
  #39 = Utf8               (Ljava/lang/Runnable;)V
  #40 = Utf8               start
  #41 = Utf8               join
{
  static int i;
    descriptor: I
    flags: ACC_STATIC

  public ThreadBasic.Synchronized.SynStatic();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."":()V
         4: return
      LineNumberTable:
        line 3: 0

  public static synchronized void increase();
    descriptor: ()V
    flags: ACC_PUBLIC, ACC_STATIC, ACC_SYNCHRONIZED
    Code:
      stack=2, locals=0, args_size=0
         0: getstatic     #2                  // Field i:I
         3: iconst_1
         4: iadd
         5: putstatic     #2                  // Field i:I
         8: return
      LineNumberTable:
        line 7: 0
        line 8: 8

  public void run();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=2, args_size=1
         0: iconst_0
         1: istore_1
         2: iload_1
         3: iconst_5
         4: if_icmpge     16
         7: invokestatic  #3                  // Method increase:()V
        10: iinc          1, 1
        13: goto          2
        16: return
      LineNumberTable:
        line 12: 0
        line 13: 7
        line 12: 10
        line 15: 16
      StackMapTable: number_of_entries = 2
        frame_type = 252 /* append */
          offset_delta = 2
          locals = [ int ]
        frame_type = 250 /* chop */
          offset_delta = 13

  public static void main(java.lang.String[]) throws java.lang.InterruptedException;
    descriptor: ([Ljava/lang/String;)V
    flags: ACC_PUBLIC, ACC_STATIC
    Code:
      stack=4, locals=2, args_size=1
         0: new           #4                  // class java/lang/Thread
         3: dup
         4: new           #5                  // class ThreadBasic/Synchronized/SynStatic
         7: dup
         8: invokespecial #6                  // Method "":()V
        11: invokespecial #7                  // Method java/lang/Thread."":(Ljava/lang/Runnable;)V
        14: astore_1
        15: aload_1
        16: invokevirtual #8                  // Method java/lang/Thread.start:()V
        19: aload_1
        20: invokevirtual #9                  // Method java/lang/Thread.join:()V
        23: return
      LineNumberTable:
        line 19: 0
        line 21: 15
        line 23: 19
        line 24: 23
    Exceptions:
      throws java.lang.InterruptedException

  static {};
    descriptor: ()V
    flags: ACC_STATIC
    Code:
      stack=1, locals=0, args_size=0
         0: iconst_0
         1: putstatic     #2                  // Field i:I
         4: return
      LineNumberTable:
        line 4: 0
}
SourceFile: "SynStatic.java"


synchronized 수식 의 정적 방법 도 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACC 를 얻 었 습 니 다.SYNCHRONIZED 표지;
총결산
synchronized 가 코드 블록 을 수식 할 때:동기 구문 블록 의 실현 은 Monitorenter 와 Monitorexit 명령 을 사용 합 니 다.그 중에서 Monitorenter 명령 은 동기 코드 블록 의 시작 위 치 를 가리 키 고 Monitorexit 명령 은 동기 코드 블록 의 끝 위 치 를 가리 킵 니 다.synchronized 수식 방법:synchronized 수식 방법 은 Monitorenter 명령 과 Monitorexit 명령 이 없 으 며 대신 ACCSYNCHRONIZED 표 지 는 이 방법 이 동기 화 방법 임 을 가리 키 며 JVM 은 이 ACC 를 통 해SYNCHRONIZED 접근 표 지 는 하나의 방법 이 동기 화 방법 인지 여 부 를 판별 하여 해당 하 는 동기 화 호출 을 수행 합 니 다.

좋은 웹페이지 즐겨찾기