Java 如果我有很多锁更新一个哈希映射,我需要什么锁来获取映射的最新值
我的地图定义如下:Java 如果我有很多锁更新一个哈希映射,我需要什么锁来获取映射的最新值,java,concurrency,Java,Concurrency,我的地图定义如下: private Map<String, TreeSet<String>> companyOrderMap = new HashMap <String, TreeSet<String>>(); 另外,线程2: lockB.lock() companyOrderMap.put(key, bids); lockB.unlock() 在并发实践中,它说如果所有操作都由同一个锁完成,那么可见性id是有保证的,但是我有两个不同的锁来编辑
private Map<String, TreeSet<String>> companyOrderMap = new HashMap <String, TreeSet<String>>();
另外,线程2:
lockB.lock()
companyOrderMap.put(key, bids);
lockB.unlock()
在并发实践中,它说如果所有操作都由同一个锁完成,那么可见性id是有保证的,但是我有两个不同的锁来编辑地图?我怎样才能获得完全的可视性
这样行吗
synchronized(companyOrderMap) {
//print all contents
}
使用多个锁是不正确的 锁(和同步块)建立“发生在之前”关系:锁的解锁发生在同一个锁的锁定之前;这意味着持有锁时发生的更新对获取锁的下一个线程可见 如果使用单独的锁,以前不会发生这种情况,因此“第二次”访问无法查看“第一次”访问所影响的更新;或者,更糟糕的是,这两个访问同时发生,并破坏了哈希映射的内部状态 相反,您只需对映射的所有访问使用一个锁(读取和写入都使用相同的锁),以确保它们连续发生,并且具有完全的可见性
您可能最好使用为并发访问而设计的
ConcurrentHashMap
。使用相同的锁可以获得正确的可见性。此代码不是线程安全的,因为线程1和线程2不会在修改HashMap时互锁,所以它们可以同时修改它。HashMap不是为同时使用而设计的。要么只使用一个锁,要么使用并发映射实现,比如ConcurrentHashMap:为什么有两个锁?您的问题基于一个基本的错误。对于性能reasons@user3809938如果代码不正确,性能将毫无意义。ConcurrentHashMap是否会阻止在某个时候修改同一对象?OP还需要一个并发集,并且可能ComputeFabSent
@chrylis onstrike-不一定;这取决于该集合是否在地图中更新一次。如果没有,锁创建的HB将确保集合内容的可见性。@chrylis onstrike-(您可能希望通过将不可修改集合(新树集(bids))
)@AndyTurner公平交易来降低无意修改的风险。考虑到现有的代码,我想我是过度防御了。
synchronized(companyOrderMap) {
//print all contents
}