You need to enable JavaScript to run this app. Java方法同步与成员锁同步的并发访问安全问题
优惠活动
大模型
产品
解决方案
定价
更多

Java方法同步与成员锁同步的并发访问安全问题

关于Java synchronized实例方法的互斥范围解答

首先明确核心结论:

  • synchronized修饰的实例方法,持有的锁是当前对象实例本身(也就是示例中Thing类的实例对象,不是它的成员变量),它的互斥范围仅针对所有同样以该Thing实例为锁对象的同步代码块/同步方法,和锁其他对象(比如它的内部成员innerThing)的同步逻辑完全无关。

你给出的示例代码中,foo()和bar()并发调用一定会出现数据竞争,原因如下:

  1. 执行synchronized void foo()时,线程获取的是this(当前Thing实例)的锁
  2. 执行bar()里的synchronized(innerThing)时,线程获取的是innerThing这个成员对象的锁
  3. 两个锁是完全独立的不同对象,不存在互斥关系,两个线程可以同时进入各自的同步块执行innerThing.mutate(),如果mutate()方法里有非原子的修改操作,就会触发数据竞争。

额外提醒:Java的同步机制完全是基于锁对象的匹配来实现互斥的,没有任何隐式的“锁了外层对象就自动保护它所有成员”的语义,只要两个同步逻辑持有的锁对象不是同一个,就不会产生互斥效果。如果要让foo和bar互斥,只要保证两者的锁对象一致即可。

如果要修复示例的数据竞争问题,可选两种修改方案:
第一种,bar也锁当前Thing实例:

public void bar() {
    synchronized(this) {
        innerThing.mutate();
    }
}

第二种,foo也锁innerThing实例:

public void foo() {
    synchronized(innerThing) {
        innerThing.mutate();
    }
}

内容的提问来源于stack exchange,提问作者aspen100

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.19 04:45:05