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
-