• JVM synchronized关键字所生成的字节码


    一、创建测试类

    package com.example.jvm.bytecode;
    
    public class MyTest2 {
    
        String str = "Welcome";
    
        private  int x = 5;
    
        public static  Integer in = 10;
    
        public static void main(String[] args) {
            MyTest2 myTest2 = new MyTest2();
    
            myTest2.setX(8);
    
            in = 20;
        }
    
        public void setX(int x){
            this.x = x;
        }
      }
    

     

    反编译MyTest2.class文件

    D:workspacestudy jvm_demouildclassesjavamaincomexamplejvmytecode>javap -verbose MyTest2.class
    Classfile /D:/workspace/study/ jvm_demo/build/classes/java/main/com/example/jvm/bytecode/MyTest2.class
      Last modified 2019-6-26; size 847 bytes
      MD5 checksum d8f82e3e7255d9a738591c52d3a5417b
      Compiled from "MyTest2.java"
    public class com.example.jvm.bytecode.MyTest2
      SourceFile: "MyTest2.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #10.#34        //  java/lang/Object."<init>":()V
       #2 = String             #35            //  Welcome
       #3 = Fieldref           #5.#36         //  com/example/jvm/bytecode/MyTest2.str:Ljava/lang/String;
       #4 = Fieldref           #5.#37         //  com/example/jvm/bytecode/MyTest2.x:I
       #5 = Class              #38            //  com/example/jvm/bytecode/MyTest2
       #6 = Methodref          #5.#34         //  com/example/jvm/bytecode/MyTest2."<init>":()V
       #7 = Methodref          #5.#39         //  com/example/jvm/bytecode/MyTest2.setX:(I)V
       #8 = Methodref          #40.#41        //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       #9 = Fieldref           #5.#42         //  com/example/jvm/bytecode/MyTest2.in:Ljava/lang/Integer;
      #10 = Class              #43            //  java/lang/Object
      #11 = Utf8               str
      #12 = Utf8               Ljava/lang/String;
      #13 = Utf8               x
      #14 = Utf8               I
      #15 = Utf8               in
      #16 = Utf8               Ljava/lang/Integer;
      #17 = Utf8               <init>
      #18 = Utf8               ()V
      #19 = Utf8               Code
      #20 = Utf8               LineNumberTable
      #21 = Utf8               LocalVariableTable
      #22 = Utf8               this
      #23 = Utf8               Lcom/example/jvm/bytecode/MyTest2;
      #24 = Utf8               main
      #25 = Utf8               ([Ljava/lang/String;)V
      #26 = Utf8               args
      #27 = Utf8               [Ljava/lang/String;
      #28 = Utf8               myTest2
      #29 = Utf8               setX
      #30 = Utf8               (I)V
      #31 = Utf8               <clinit>
      #32 = Utf8               SourceFile
      #33 = Utf8               MyTest2.java
      #34 = NameAndType        #17:#18        //  "<init>":()V
      #35 = Utf8               Welcome
      #36 = NameAndType        #11:#12        //  str:Ljava/lang/String;
      #37 = NameAndType        #13:#14        //  x:I
      #38 = Utf8               com/example/jvm/bytecode/MyTest2
      #39 = NameAndType        #29:#30        //  setX:(I)V
      #40 = Class              #44            //  java/lang/Integer
      #41 = NameAndType        #45:#46        //  valueOf:(I)Ljava/lang/Integer;
      #42 = NameAndType        #15:#16        //  in:Ljava/lang/Integer;
      #43 = Utf8               java/lang/Object
      #44 = Utf8               java/lang/Integer
      #45 = Utf8               valueOf
      #46 = Utf8               (I)Ljava/lang/Integer;
    {
      java.lang.String str;
        flags:
    
      public static java.lang.Integer in;
        flags: ACC_PUBLIC, ACC_STATIC
    
      public com.example.jvm.bytecode.MyTest2();
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String Welcome
             7: putfield      #3                  // Field str:Ljava/lang/String;
            10: aload_0
            11: iconst_5
            12: putfield      #4                  // Field x:I
            15: return
          LineNumberTable:
            line 3: 0
            line 5: 4
            line 7: 10
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      16     0  this   Lcom/example/jvm/bytecode/MyTest2;
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=2, args_size=1
             0: new           #5                  // class com/example/jvm/bytecode/MyTest2
             3: dup
             4: invokespecial #6                  // Method "<init>":()V
             7: astore_1
             8: aload_1
             9: bipush        8
            11: invokevirtual #7                  // Method setX:(I)V
            14: bipush        20
            16: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
            19: putstatic     #9                  // Field in:Ljava/lang/Integer;
            22: return
          LineNumberTable:
            line 12: 0
            line 14: 8
            line 16: 14
            line 17: 22
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      23     0  args   [Ljava/lang/String;
                   8      15     1 myTest2   Lcom/example/jvm/bytecode/MyTest2;
    
      public void setX(int);
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: iload_1
             2: putfield      #4                  // Field x:I
             5: return
          LineNumberTable:
            line 20: 0
            line 21: 5
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0       6     0  this   Lcom/example/jvm/bytecode/MyTest2;
                   0       6     1     x   I
    
      static {};
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: bipush        10
             2: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
             5: putstatic     #9                  // Field in:Ljava/lang/Integer;
             8: return
          LineNumberTable:
            line 9: 0
    }
    

      

    二、将setX改为private

    此时需要使用javap -verbose -p  MyTest2.class才能显示私有方法

    D:workspacestudy jvm_demouildclassesjavamaincomexamplejvmytecode>javap -verbose -p  MyTest2.class
    Classfile /D:/workspace/study/ jvm_demo/build/classes/java/main/com/example/jvm/bytecode/MyTest2.class
      Last modified 2019-6-27; size 847 bytes
      MD5 checksum f9ed848bb768588b932c395b40c509a8
      Compiled from "MyTest2.java"
    public class com.example.jvm.bytecode.MyTest2
      SourceFile: "MyTest2.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #10.#34        //  java/lang/Object."<init>":()V
       #2 = String             #35            //  Welcome
       #3 = Fieldref           #5.#36         //  com/example/jvm/bytecode/MyTest2.str:Ljava/lang/String;
       #4 = Fieldref           #5.#37         //  com/example/jvm/bytecode/MyTest2.x:I
       #5 = Class              #38            //  com/example/jvm/bytecode/MyTest2
       #6 = Methodref          #5.#34         //  com/example/jvm/bytecode/MyTest2."<init>":()V
       #7 = Methodref          #5.#39         //  com/example/jvm/bytecode/MyTest2.setX:(I)V
       #8 = Methodref          #40.#41        //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       #9 = Fieldref           #5.#42         //  com/example/jvm/bytecode/MyTest2.in:Ljava/lang/Integer;
      #10 = Class              #43            //  java/lang/Object
      #11 = Utf8               str
      #12 = Utf8               Ljava/lang/String;
      #13 = Utf8               x
      #14 = Utf8               I
      #15 = Utf8               in
      #16 = Utf8               Ljava/lang/Integer;
      #17 = Utf8               <init>
      #18 = Utf8               ()V
      #19 = Utf8               Code
      #20 = Utf8               LineNumberTable
      #21 = Utf8               LocalVariableTable
      #22 = Utf8               this
      #23 = Utf8               Lcom/example/jvm/bytecode/MyTest2;
      #24 = Utf8               main
      #25 = Utf8               ([Ljava/lang/String;)V
      #26 = Utf8               args
      #27 = Utf8               [Ljava/lang/String;
      #28 = Utf8               myTest2
      #29 = Utf8               setX
      #30 = Utf8               (I)V
      #31 = Utf8               <clinit>
      #32 = Utf8               SourceFile
      #33 = Utf8               MyTest2.java
      #34 = NameAndType        #17:#18        //  "<init>":()V
      #35 = Utf8               Welcome
      #36 = NameAndType        #11:#12        //  str:Ljava/lang/String;
      #37 = NameAndType        #13:#14        //  x:I
      #38 = Utf8               com/example/jvm/bytecode/MyTest2
      #39 = NameAndType        #29:#30        //  setX:(I)V
      #40 = Class              #44            //  java/lang/Integer
      #41 = NameAndType        #45:#46        //  valueOf:(I)Ljava/lang/Integer;
      #42 = NameAndType        #15:#16        //  in:Ljava/lang/Integer;
      #43 = Utf8               java/lang/Object
      #44 = Utf8               java/lang/Integer
      #45 = Utf8               valueOf
      #46 = Utf8               (I)Ljava/lang/Integer;
    {
      java.lang.String str;
        flags:
    
      private int x;
        flags: ACC_PRIVATE
    
      public static java.lang.Integer in;
        flags: ACC_PUBLIC, ACC_STATIC
    
      public com.example.jvm.bytecode.MyTest2();
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String Welcome
             7: putfield      #3                  // Field str:Ljava/lang/String;
            10: aload_0
            11: iconst_5
            12: putfield      #4                  // Field x:I
            15: return
          LineNumberTable:
            line 3: 0
            line 5: 4
            line 7: 10
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      16     0  this   Lcom/example/jvm/bytecode/MyTest2;
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=2, args_size=1
             0: new           #5                  // class com/example/jvm/bytecode/MyTest2
             3: dup
             4: invokespecial #6                  // Method "<init>":()V
             7: astore_1
             8: aload_1
             9: bipush        8
            11: invokespecial #7                  // Method setX:(I)V
            14: bipush        20
            16: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
            19: putstatic     #9                  // Field in:Ljava/lang/Integer;
            22: return
          LineNumberTable:
            line 12: 0
            line 14: 8
            line 16: 14
            line 17: 22
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      23     0  args   [Ljava/lang/String;
                   8      15     1 myTest2   Lcom/example/jvm/bytecode/MyTest2;
    
      private void setX(int);
        flags: ACC_PRIVATE
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: iload_1
             2: putfield      #4                  // Field x:I
             5: return
          LineNumberTable:
            line 20: 0
            line 21: 5
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0       6     0  this   Lcom/example/jvm/bytecode/MyTest2;
                   0       6     1     x   I
    
      static {};
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: bipush        10
             2: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
             5: putstatic     #9                  // Field in:Ljava/lang/Integer;
             8: return
          LineNumberTable:
            line 9: 0
    }
    View Code

    三、现在将setX方法增加synchronized 修饰符

    private synchronized void setX(int x)
    反编译后无synchronized和有synchronized的区别如下图:

    
    

    四、在类中增加test方法,方法里面使用了synchronize

        private void test(String str){
            synchronized (obj){
                System.out.println("hello world");
            }
        }
    

      反编译后如下:

     private void test(java.lang.String);
        flags: ACC_PRIVATE
        Code:
          stack=2, locals=4, args_size=2
             0: aload_0
             1: getfield      #6                  // Field obj:Ljava/lang/Object;
             4: dup
             5: astore_2
             6: monitorenter
             7: getstatic     #12                 // Field java/lang/System.out:Ljava/io/PrintStream;
            10: ldc           #13                 // String hello world
            12: invokevirtual #14                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            15: aload_2
            16: monitorexit
            17: goto          25
            20: astore_3
            21: aload_2
            22: monitorexit
            23: aload_3
            24: athrow
            25: return
          Exception table:
             from    to  target type
                 7    17    20   any
                20    23    20   any
          LineNumberTable:
            line 26: 0
            line 27: 7
            line 28: 15
            line 29: 25
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      26     0  this   Lcom/example/jvm/bytecode/MyTest2;
                   0      26     1   str   Ljava/lang/String;
          StackMapTable: number_of_entries = 2
               frame_type = 255 /* full_frame */
              offset_delta = 20
              locals = [ class com/example/jvm/bytecode/MyTest2, class java/lang/String, class java/lang/Object ]
              stack = [ class java/lang/Throwable ]
               frame_type = 250 /* chop */
              offset_delta = 4
    

      出现了6: monitorenter和22: monitorexit

    给当前MyTest2类所对应的class对象上锁

    private synchronized static void test2(){

    }

    给当前对象上锁

    private synchronized void setX(int x){
    this.x = x;
    }

    五、字节码文件分析

    最终需要分析的java文件

    package com.example.jvm.bytecode;
    
    public class MyTest2 {
    
        String str = "Welcome";
    
        private  int x = 5;
    
        public static  Integer in = 10;
    
        public static void main(String[] args) {
            MyTest2 myTest2 = new MyTest2();
    
            myTest2.setX(8);
    
            in = 20;
        }
    
        private synchronized void setX(int x){
            this.x = x;
        }
    
        private void test(String str){
            synchronized (str){
                System.out.println("hello world");
            }
        }
    
        private synchronized static void test2(){
    
        }
      }
    

      然后反编译MyTest2.class

    Classfile /D:/workspace/study/ jvm_demo/build/classes/java/main/com/example/jvm/bytecode/MyTest2.class
      Last modified 2019-6-27; size 1265 bytes
      MD5 checksum 1ca3fedabb74af431cc850f3f87b7763
      Compiled from "MyTest2.java"
    public class com.example.jvm.bytecode.MyTest2
      SourceFile: "MyTest2.java"
      minor version: 0
      major version: 51
      flags: ACC_PUBLIC, ACC_SUPER
    Constant pool:
       #1 = Methodref          #13.#45        //  java/lang/Object."<init>":()V
       #2 = String             #46            //  Welcome
       #3 = Fieldref           #5.#47         //  com/example/jvm/bytecode/MyTest2.str:Ljava/lang/String;
       #4 = Fieldref           #5.#48         //  com/example/jvm/bytecode/MyTest2.x:I
       #5 = Class              #49            //  com/example/jvm/bytecode/MyTest2
       #6 = Methodref          #5.#45         //  com/example/jvm/bytecode/MyTest2."<init>":()V
       #7 = Methodref          #5.#50         //  com/example/jvm/bytecode/MyTest2.setX:(I)V
       #8 = Methodref          #51.#52        //  java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       #9 = Fieldref           #5.#53         //  com/example/jvm/bytecode/MyTest2.in:Ljava/lang/Integer;
      #10 = Fieldref           #54.#55        //  java/lang/System.out:Ljava/io/PrintStream;
      #11 = String             #56            //  hello world
      #12 = Methodref          #57.#58        //  java/io/PrintStream.println:(Ljava/lang/String;)V
      #13 = Class              #59            //  java/lang/Object
      #14 = Utf8               str
      #15 = Utf8               Ljava/lang/String;
      #16 = Utf8               x
      #17 = Utf8               I
      #18 = Utf8               in
      #19 = Utf8               Ljava/lang/Integer;
      #20 = Utf8               <init>
      #21 = Utf8               ()V
      #22 = Utf8               Code
      #23 = Utf8               LineNumberTable
      #24 = Utf8               LocalVariableTable
      #25 = Utf8               this
      #26 = Utf8               Lcom/example/jvm/bytecode/MyTest2;
      #27 = Utf8               main
      #28 = Utf8               ([Ljava/lang/String;)V
      #29 = Utf8               args
      #30 = Utf8               [Ljava/lang/String;
      #31 = Utf8               myTest2
      #32 = Utf8               setX
      #33 = Utf8               (I)V
      #34 = Utf8               test
      #35 = Utf8               (Ljava/lang/String;)V
      #36 = Utf8               StackMapTable
      #37 = Class              #49            //  com/example/jvm/bytecode/MyTest2
      #38 = Class              #60            //  java/lang/String
      #39 = Class              #59            //  java/lang/Object
      #40 = Class              #61            //  java/lang/Throwable
      #41 = Utf8               test2
      #42 = Utf8               <clinit>
      #43 = Utf8               SourceFile
      #44 = Utf8               MyTest2.java
      #45 = NameAndType        #20:#21        //  "<init>":()V
      #46 = Utf8               Welcome
      #47 = NameAndType        #14:#15        //  str:Ljava/lang/String;
      #48 = NameAndType        #16:#17        //  x:I
      #49 = Utf8               com/example/jvm/bytecode/MyTest2
      #50 = NameAndType        #32:#33        //  setX:(I)V
      #51 = Class              #62            //  java/lang/Integer
      #52 = NameAndType        #63:#64        //  valueOf:(I)Ljava/lang/Integer;
      #53 = NameAndType        #18:#19        //  in:Ljava/lang/Integer;
      #54 = Class              #65            //  java/lang/System
      #55 = NameAndType        #66:#67        //  out:Ljava/io/PrintStream;
      #56 = Utf8               hello world
      #57 = Class              #68            //  java/io/PrintStream
      #58 = NameAndType        #69:#35        //  println:(Ljava/lang/String;)V
      #59 = Utf8               java/lang/Object
      #60 = Utf8               java/lang/String
      #61 = Utf8               java/lang/Throwable
      #62 = Utf8               java/lang/Integer
      #63 = Utf8               valueOf
      #64 = Utf8               (I)Ljava/lang/Integer;
      #65 = Utf8               java/lang/System
      #66 = Utf8               out
      #67 = Utf8               Ljava/io/PrintStream;
      #68 = Utf8               java/io/PrintStream
      #69 = Utf8               println
    {
      java.lang.String str;
        flags:
    
      private int x;
        flags: ACC_PRIVATE
    
      public static java.lang.Integer in;
        flags: ACC_PUBLIC, ACC_STATIC
    
      public com.example.jvm.bytecode.MyTest2();
        flags: ACC_PUBLIC
        Code:
          stack=2, locals=1, args_size=1
             0: aload_0
             1: invokespecial #1                  // Method java/lang/Object."<init>":()V
             4: aload_0
             5: ldc           #2                  // String Welcome
             7: putfield      #3                  // Field str:Ljava/lang/String;
            10: aload_0
            11: iconst_5
            12: putfield      #4                  // Field x:I
            15: return
          LineNumberTable:
            line 3: 0
            line 5: 4
            line 7: 10
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      16     0  this   Lcom/example/jvm/bytecode/MyTest2;
    
      public static void main(java.lang.String[]);
        flags: ACC_PUBLIC, ACC_STATIC
        Code:
          stack=2, locals=2, args_size=1
             0: new           #5                  // class com/example/jvm/bytecode/MyTest2
             3: dup
             4: invokespecial #6                  // Method "<init>":()V
             7: astore_1
             8: aload_1
             9: bipush        8
            11: invokespecial #7                  // Method setX:(I)V
            14: bipush        20
            16: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
            19: putstatic     #9                  // Field in:Ljava/lang/Integer;
            22: return
          LineNumberTable:
            line 12: 0
            line 14: 8
            line 16: 14
            line 17: 22
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      23     0  args   [Ljava/lang/String;
                   8      15     1 myTest2   Lcom/example/jvm/bytecode/MyTest2;
    
      private synchronized void setX(int);
        flags: ACC_PRIVATE, ACC_SYNCHRONIZED
        Code:
          stack=2, locals=2, args_size=2
             0: aload_0
             1: iload_1
             2: putfield      #4                  // Field x:I
             5: return
          LineNumberTable:
            line 20: 0
            line 21: 5
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0       6     0  this   Lcom/example/jvm/bytecode/MyTest2;
                   0       6     1     x   I
    
      private void test(java.lang.String);
        flags: ACC_PRIVATE
        Code:
          stack=2, locals=4, args_size=2
             0: aload_1
             1: dup
             2: astore_2
             3: monitorenter
             4: getstatic     #10                 // Field java/lang/System.out:Ljava/io/PrintStream;
             7: ldc           #11                 // String hello world
             9: invokevirtual #12                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
            12: aload_2
            13: monitorexit
            14: goto          22
            17: astore_3
            18: aload_2
            19: monitorexit
            20: aload_3
            21: athrow
            22: return
          Exception table:
             from    to  target type
                 4    14    17   any
                17    20    17   any
          LineNumberTable:
            line 24: 0
            line 25: 4
            line 26: 12
            line 27: 22
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                   0      23     0  this   Lcom/example/jvm/bytecode/MyTest2;
                   0      23     1   str   Ljava/lang/String;
          StackMapTable: number_of_entries = 2
               frame_type = 255 /* full_frame */
              offset_delta = 17
              locals = [ class com/example/jvm/bytecode/MyTest2, class java/lang/String, class java/lang/Object ]
              stack = [ class java/lang/Throwable ]
               frame_type = 250 /* chop */
              offset_delta = 4
    
    
      private static synchronized void test2();
        flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNCHRONIZED
        Code:
          stack=0, locals=0, args_size=0
             0: return
          LineNumberTable:
            line 31: 0
    
      static {};
        flags: ACC_STATIC
        Code:
          stack=1, locals=0, args_size=0
             0: bipush        10
             2: invokestatic  #8                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
             5: putstatic     #9                  // Field in:Ljava/lang/Integer;
             8: return
          LineNumberTable:
            line 9: 0
    }

    然后打开WinHex打开MyTest2.class 文件

  • 相关阅读:
    当Django模型迁移时,报No migrations to apply 问题时
    django--各个文件的含义
    django--创建项目
    1013. Battle Over Cities (25)
    1011. World Cup Betting (20)
    1009. Product of Polynomials (25)
    1007. Maximum Subsequence Sum (25)
    1006. Sign In and Sign Out (25)
    1008. Elevator (20)
    1004. Counting Leaves (30)
  • 原文地址:https://www.cnblogs.com/linlf03/p/11097179.html
Copyright © 2020-2023  润新知