Java 嵌套同步方法的开销
考虑以下两个例子: 例1: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()
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()中使用。