Java 嵌套同步方法的开销

Java 嵌套同步方法的开销,java,multithreading,synchronization,synchronized,Java,Multithreading,Synchronization,Synchronized,考虑以下两个例子: 例1: Class A { private final B b = new B(); public synchronized void m1() { b.m2(); } } Class B { public void m2() { // do something } } 例2: Class A { B b = new B(); public synchronized void m1()

考虑以下两个例子:

例1:

Class A {
    private final B b = new B();
    public synchronized void m1() {
        b.m2();
    }
}
Class B {
    public void m2() {
        // do something
    }
}
例2:

Class A {
    B b = new B();
    public synchronized void m1() {
        b.m2();
    }
}
Class B {
    public synchronized void m2() {
        // do something
    }
}
假设B.m2()仅在A.m1()中调用,
如果B.m2()已经被A.m1()保护,那么同步B.m2()的成本是多少?i、 与示例1相比,示例2是否增加了任何开销?JVM是否对示例2进行了优化,使其看起来像示例1?

如果同步
m2
,则会有一些开销,因为在输入
m2
时,线程仍必须获取
b
对象上的锁(如果锁始终是空闲的,则会发生事件)

如果启用了转义分析,JVM可能会发现同步是冗余的,并对其进行优化(即从
m2
中删除
synchronized
)。如果代码能够得到优化,那么就不会有性能差异。消除冗余同步的优化称为锁省略或锁粗化


有关逃逸分析的更多详细信息,请参见以下内容。

它还没有受到A的m1的保护。A中的synchronized确保没有其他线程可以在不首先获得A对象的锁的情况下调用A.m1()。但是,任何引用了B的线程都可以调用B.m2(),即使在B.m2()未同步的情况下,a已经在调用它。@JBNizet假设没有其他线程可以引用B,并且B只在a.m1()中使用。