嵌套同步块的HotSpot JVM优化

时间:2014-07-21 01:15:45

标签: java optimization synchronization synchronized jvm-hotspot

HotSpot JVM(在Oracle JDK 7和8中)是否针对在同一对象上同步的嵌套synchronized块进行优化?

例如,第一个代码清单(类A)和第二个代码清单(类B)一样高效吗? (类B避免出现在synchronized (x)类中的嵌套A

public class A {
    private final Object x = new Object();

    public void a() {
        synchronized (x) {
            // code snippet 1
            b();
            // code snippet 2
        }
    }

    public void b() {
        synchronized (x) {
            // code snippet 3
        }
    }
}

public class B {
    private final Object x = new Object();

    public void a() {
        synchronized (x) {
            // code snippet 1
            c();
            // code snippet 2
        }
    }

    public void b() {
        synchronized (x) {
            c();
        }
    }

    private void c() {
        // code snippet 3
    }
}

2 个答案:

答案 0 :(得分:1)

是的,甚至还有一个VM选项出现在JDK 7中(默认情况下已启用):

-XX:+EliminateNestedLocks

但是,它似乎仅在监视对象为static final或锁定this对象时才有效。

答案 1 :(得分:0)

如果b足够短,可以内联,我希望如此。否则,因为程序间分析太复杂而且增益受限(无法内联的内容可能需要很长时间才能接受一些开销)。但是你仍然可以从有偏见的锁定中获利。

这只是一个猜测,但即使是JDK6也会lock coarsening,这可以被认为是你所询问的更复杂的版本。内联后我们有

public void a() {
    synchronized (x) {
        // code snippet 1
        synchronized (x) {
            // code snippet 3
        }
        // code snippet 2
    }
}

虽然锁定粗化以

之类的东西开始
public void a() {
    synchronized (x) {
        // code snippet 1
    }
    synchronized (x) {
        // code snippet 3
    }
    synchronized (x) {
        // code snippet 2
    }
}

这是一个更复杂的情况,因为加入同步块会降低吞吐量,而在你的情况下绝对没有什么可失去的。