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
相关产品推荐
相关产品推荐

