为什么synchronized关键字不会每次都创建监视器

sab*_*sab 1 java

为什么synchronized关键字不会创建监视器每次使用时都在字节码级别输入?

NPE*_*NPE 8

synchronized关键字可以以两种方式使用:

  1. 当您synchronized(obj)在函数体内使用时,编译器将为相关监视器发出monitorenter/ monitorexit字节码.

  2. 如果声明了整个方法synchronized,则在字节码中将该方法标记为ACC_SYNCHRONIZED.进入/退出方法时,JVM将隐式进入和退出监视器.不发出monitorenter/ monitorexit字节码,也不需要.

考虑以下两种方法:

public class Sync {

    public void f() {
        synchronized (this) {
        }
    }

    public synchronized void g() {
    }

}
Run Code Online (Sandbox Code Playgroud)

他们编译为:

public void f();
  Code:
   0:   aload_0
   1:   dup
   2:   monitorenter
   3:   monitorexit
   4:   return

public synchronized void g();
  Code:
   0:   return
Run Code Online (Sandbox Code Playgroud)

如您所见,g()仍然synchronized在字节码中标记,因此JVM知道该怎么做.

免责声明:这是我的编译器所做的.似乎有可能不同的编译器可能选择发出monitorenter/ monitorexit而不是使用ACC_SYNCHRONIZED.我不知道是否有任何现有的编译器都这样做.