深入理解Java虚拟机(四)

synchronized 字节码分析

我们先来看一下一个简单的方法

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @Author: cuzz
* @Date: 2019/3/4 13:34
* @Description:
*/
public class MyTest02 {
int x = 0;

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

使用 javap -v com.cuzz.jvm.bytecode.MyTest02 命令,找到 setX 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void setX(int);
descriptor: (I)V
flags: ACC_PUBLIC
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: iload_1
2: putfield #2 // Field x:I
5: return
LineNumberTable:
line 12: 0
line 13: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/cuzz/jvm/bytecode/MyTest02;
0 6 1 x I

如果我们在方法中添加 synchronzied 关键字

1
2
3
4
5
6
7
public class MyTest02 {
int x = 0;

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

我们再反编译一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public synchronized void setX(int);
descriptor: (I)V
flags: ACC_PUBLIC, ACC_SYNCHRONIZED
Code:
stack=2, locals=2, args_size=2
0: aload_0
1: iload_1
2: putfield #2 // Field x:I
5: return
LineNumberTable:
line 12: 0
line 13: 5
LocalVariableTable:
Start Length Slot Name Signature
0 6 0 this Lcom/cuzz/jvm/bytecode/MyTest02;
0 6 1 x I

对比这两个反编译的结果,我们发现在 flags 中多了 ACC_SYNCHRONIZED,不会出现 monitorenter 和 monitorexit。

如果我们是在方法体重添加 synchronized 关键字

1
2
3
4
5
6
7
8
9
10
public class MyTest02 {
String lock = "lock";
int x = 0;

public int getX() {
synchronized (lock) {
return x;
}
}
}

我们反编译一下 找到 getX 方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public int getX();
descriptor: ()I
flags: ACC_PUBLIC
Code:
stack=2, locals=3, args_size=1
0: aload_0
1: getfield #3 // Field lock:Ljava/lang/String;
4: dup
5: astore_1
6: monitorenter
7: aload_0
8: getfield #4 // Field x:I
11: aload_1
12: monitorexit
13: ireturn
14: astore_2
15: aload_1
16: monitorexit
17: aload_2
18: athrow
Exception table:
from to target type
7 13 14 any
14 17 14 any
LineNumberTable:
line 17: 0
line 18: 7
line 19: 14
LocalVariableTable:
Start Length Slot Name Signature
0 19 0 this Lcom/cuzz/jvm/bytecode/MyTest02;
StackMapTable: number_of_entries = 1
frame_type = 255 /* full_frame */
offset_delta = 14
locals = [ class com/cuzz/jvm/bytecode/MyTest02, class java/lang/Object ]
stack = [ class java/lang/Throwable ]

在 6 中出现 monitorenter,在 16 中出现 moniterexit

-------------本文结束感谢您的阅读-------------

本文标题:深入理解Java虚拟机(四)

文章作者:cuzz

发布时间:2019年03月04日 - 23:03

最后更新:2019年08月01日 - 23:08

原始链接:http://blog.cuzz.site/2019/03/04/深入理解Java虚拟机(四)/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

请博主吃包辣条
0%