You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中如何为对象的不同成员设置不同的同步代码块

Java中用独立锁保护不同资源的实现方案

嘿,这个问题戳中了从C/C转Java时常见的同步机制适配点!我来给你理清楚怎么实现和C/C里双mutex保护不同资源一模一样的逻辑。

首先得明确:Java里的synchronized关键字本质是对象锁——当你写synchronized(obj)时,线程会尝试获取obj这个对象的内置锁(intrinsic lock),同一时间只有一个线程能持有这个锁。所以如果你的两个同步代码块用的是同一个锁对象,那肯定不能同时进入;但如果用两个完全独立的锁对象,就和C/C++里两个mutex的效果完全一致,两个线程可以同时修改i和j,互不干扰。

具体实现代码示例

直接上代码,一看就懂:

public class ResourceHolder {
    private int i;
    private int j;
    
    // 定义两个独立的锁对象,专门用来分别保护i和j
    private final Object lockForI = new Object();
    private final Object lockForJ = new Object();
    
    public void setI(int newValue) {
        // 用lockForI保护对i的修改
        synchronized (lockForI) {
            this.i = newValue;
            // 其他和i相关的临界区操作也放这里
        }
    }
    
    public void setJ(int newValue) {
        // 用lockForJ保护对j的修改
        synchronized (lockForJ) {
            this.j = newValue;
            // 其他和j相关的临界区操作也放这里
        }
    }
    
    // 如果有读取操作,也要用对应的锁,保证可见性和原子性
    public int getI() {
        synchronized (lockForI) {
            return this.i;
        }
    }
    
    public int getJ() {
        synchronized (lockForJ) {
            return this.j;
        }
    }
}

关键说明

  • 这里的lockForI和lockForJ就对应你C/C++里的两个mutex变量,完全独立,各自管各自的资源。
  • 一定要用私有、final的对象当锁:私有是为了防止外部代码随意获取锁导致逻辑混乱,final是为了保证锁对象不会被替换,避免出现锁失效的问题。
  • 别犯用成员变量本身当锁的错误(比如synchronized(Integer.valueOf(i))),因为Java的包装类有缓存机制,可能导致不同的数值共用同一个对象,锁就串了。

这样实现后,当一个线程调用setI进入synchronized(lockForI)块时,另一个线程完全可以同时调用setJ进入synchronized(lockForJ)块,和你在C/C++里用两个mutex分别保护i、j的效果完全一致!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:15:40