【问题标题】:Overhead of nested synchronized methods嵌套同步方法的开销
【发布时间】:2018-10-27 08:34:17
【问题描述】:

考虑以下 2 个示例:

示例 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() 的成本是多少?即,与示例 1 相比,示例 2 是否增加了任何开销? JVM 是否优化了示例 2 使其看起来像示例 1?

【问题讨论】:

  • 它还没有被A的m1守护。 A 中的同步确保在没有首先获得A 对象 的锁之前没有其他线程可以调用A.m1()。但是任何引用 B 的线程都可以调用 B.m2(),即使 A 已经在调用它,如果 B.m2() 没有同步。
  • @JBNizet 假设没有其他线程可以引用 B 并且 B 仅在 A.m1() 中使用。

标签: java multithreading synchronization synchronized


【解决方案1】:

如果您同步m2,则会涉及一些开销,因为当进入m2 时,线程仍然需要获取b 对象上的锁(如果锁始终是空闲的,则事件)。

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

更多逃逸分析详情请看以下link。

【讨论】:

    猜你喜欢
    • 2012-06-05
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 2020-11-04
    • 1970-01-01
    相关资源
    最近更新 更多