为什么synchronized关键字不会创建监视器每次使用时都在字节码级输入?
答案 0 :(得分:7)
synchronized
关键字可以通过两种方式使用:
在函数体内使用synchronized(obj)
时,编译器将为相关监视器发出monitorenter
/ monitorexit
个字节码。
如果整个方法声明为synchronized
,则在字节码中,该方法将被标记为ACC_SYNCHRONIZED
。进入/退出方法时,JVM将隐式进入和退出监视器。不会发出monitorenter
/ monitorexit
个字节码,也不需要。
考虑以下两种方法:
public class Sync {
public void f() {
synchronized (this) {
}
}
public synchronized void g() {
}
}
他们编译为:
public void f();
Code:
0: aload_0
1: dup
2: monitorenter
3: monitorexit
4: return
public synchronized void g();
Code:
0: return
如您所见,g()
仍然在字节码中标记为synchronized
,因此JVM知道该怎么做。
免责声明:这就是我的编译器所做的事情。似乎可能不同的编译器可能选择发出monitorenter
/ monitorexit
而不是使用ACC_SYNCHRONIZED
。无论现有的编译器是否这样做,我都不知道。
答案 1 :(得分:0)
synchronized关键字不会创建监视器
互斥锁或监视器本身就是对象。
在Java中,synchronized
关键字是implicit
锁定,即它使用对象iternal锁定进行同步