46-synchronized关键字所生成的字节码详细分析

synchronized关键字所生成的字节码详细分析

1.synchronized 的 可重入锁和不可重入锁!!!!

  • MyTest2
package 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(){
        
    }
}
  • MyTest.class文件分析:

    • 对上面的test方法进行分析:
     private void test(java.lang.String);
        descriptor: (Ljava/lang/String;)V
        flags: ACC_PRIVATE
        Code:
          stack=2, locals=4, args_size=2
             0: aload_1
             1: dup
             2: astore_2
             3: monitorenter			//★★★获取锁,进入的synchronized代码块中
             // Field java/lang/System.out:Ljava/io/PrintStream;
             4: getstatic     #10
             // String hello world
             7: ldc           #11
             // Method java/io/PrintStream.println:(Ljava/lang/String;)V
             9: invokevirtual #12                 
            12: aload_2
            13: monitorexit				//★★★正常的释放锁,出synchronized代码块
            14: goto          22
            17: astore_3
            18: aload_2
            19: monitorexit				//★★★异常的释放锁,出synchronized代码块(out流)
            20: aload_3
            21: athrow
            22: return
          Exception table:
             from    to  target type
                 4    14    17   any
                17    20    17   any
          LineNumberTable:
            line 23: 0
            line 24: 4
            line 25: 12
            line 26: 22
          LocalVariableTable:
            Start  Length  Slot  Name   Signature
                0      23     0  this   Ljvm/bytecode/MyTest2;
                0      23     1   str   Ljava/lang/String;
          StackMapTable: number_of_entries = 2
            frame_type = 255 /* full_frame */
              offset_delta = 17
              locals = [ class jvm/bytecode/MyTest2, class java/lang/String, class java/lang/Object ]
              stack = [ class java/lang/Throwable ]
            frame_type = 250 /* chop */
              offset_delta = 4
    
    
    • 对test2()方法进行分析:

      • 当synchronized修饰的是静态方法的时候,实际上synchronized是给当前的MyTest2类所对应的class对象上的锁。

      • 这里仅仅是多了一个flag,在Code中是看不到:monitorenter、monitorexit

        private static synchronized void test2();
            descriptor: ()V
            flags: ACC_PRIVATE, ACC_STATIC, ACC_SYNCHRONIZED 
            Code:
              stack=0, locals=0, args_size=0
                 0: return
              LineNumberTable:
                line 30: 0
        
上一篇:[每日一题2020.06.24]leetcode #46 dfs


下一篇:省选模拟46