synchronized是很多小伙伴都使用过的代码同不关键字,接下来我们看一下synchronized在字节码层面是如何实现的
先上代码
public class Main {
public static void main(String[] args) throws InterruptedException {}
public void m() {
Object object = new Object();
synchronized (object) {
}
}
}
这个代码其实没有任务逻辑,就是有个m方法,并且在方法中有个空的synchronized代码块
下面我们使用idea中的工具看一下字节码 view->show Bytecode
public m()V
TRYCATCHBLOCK L0 L1 L2 null
TRYCATCHBLOCK L2 L3 L2 null
L4
LINENUMBER 12 L4
NEW java/lang/Object
DUP
INVOKESPECIAL java/lang/Object.<init> ()V
ASTORE 1
L5
LINENUMBER 13 L5
ALOAD 1
DUP
ASTORE 2
MONITORENTER
L0
LINENUMBER 14 L0
ALOAD 2
MONITOREXIT
L1
GOTO L6
L2
FRAME FULL [org/example/Main java/lang/Object java/lang/Object] [java/lang/Throwable]
ASTORE 3
ALOAD 2
MONITOREXIT
L3
ALOAD 3
ATHROW
L6
LINENUMBER 15 L6
FRAME CHOP 1
RETURN
L7
LOCALVARIABLE this Lorg/example/Main; L4 L7 0
LOCALVARIABLE object Ljava/lang/Object; L5 L7 1
MAXSTACK = 2
MAXLOCALS = 4
我们重点关注一下下面一段代码
MONITORENTER
L0
LINENUMBER 13 L0
ALOAD 1
MONITOREXIT
这里这就是synchronized在字节码层面的实现接下来我们看下去除synchronized块后的字节码
public m()V
L0
LINENUMBER 12 L0
NEW java/lang/Object
DUP
INVOKESPECIAL java/lang/Object.<init> ()V
ASTORE 1
L1
LINENUMBER 13 L1
RETURN
L2
LOCALVARIABLE this Lorg/example/Main; L0 L2 0
LOCALVARIABLE object Ljava/lang/Object; L1 L2 1
MAXSTACK = 2
MAXLOCALS = 2
从前后两份字节码可以明显看出MONITORENTER 和 MONITOREXIT被去除了,从这里我们可以知道了synchronized在字节码层面的实现
synchronized同步代码块中就在字节码层面上实现如下
MONITORENTER
...
我们的同步代码块
...
MONITOREXIT