Java 集合中的synchronizedMap方法是否同步读写操作
当我执行Collections.synchronizedMap(someHashMap)时,是否所有对映射的访问都是同步的?还是仅同步写入操作(put)? 如果有两个线程正在从地图上读取数据呢?会同步吗?似乎没有必要Java 集合中的synchronizedMap方法是否同步读写操作,java,collections,map,synchronized,java-5,Java,Collections,Map,Synchronized,Java 5,当我执行Collections.synchronizedMap(someHashMap)时,是否所有对映射的访问都是同步的?还是仅同步写入操作(put)? 如果有两个线程正在从地图上读取数据呢?会同步吗?似乎没有必要 如果一个线程在执行put(),另一个线程在执行get(),该如何处理?请查看包装映射的同步映射的源代码 ... public V get(Object key) { synchronized (mutex) {return m.get(key);} } public V
如果一个线程在执行put(),另一个线程在执行get(),该如何处理?请查看包装
映射的同步映射的源代码
...
public V get(Object key) {
synchronized (mutex) {return m.get(key);}
}
public V put(K key, V value) {
synchronized (mutex) {return m.put(key, value);}
}
public V remove(Object key) {
synchronized (mutex) {return m.remove(key);}
}
... // more methods synchronized in the same way
从
公共静态映射同步映射(映射m){
返回新的同步地图(m);
}
因此,是的,所有访问都是同步的。是的,它同步所有操作。它不使用多读卡器、单写卡器的方法,只需通过一个监视器同步所有访问即可。读取和写入都是同步的,这是确保可见性所必需的。对集合的所有方法调用都是同步的。一次只允许一个线程读取/修改集合
集合中的synchronized*方法不是设计为最佳线程安全版本/实现的。他们只是被认为是方便的
同步是一个困难的问题,通常需要根据特定场景采用不同的同步方法。如果您需要其他类型的线程安全,那么还有很多其他的线程安全集合可用。您也可以自己编写同步逻辑。因为Collections.synchronizedMap
非常基本,几乎无法使用。有ConcurrentHashMap
用于更严重的并发使用。但不幸的是,读取和写入在内部互斥体上同步,这使得外部代码不可能在持有锁的同时迭代整个实体。编辑:Sotirios和Affe是正确的,我的评论应该被忽略。这就是javadoc所说的:当用户在其任何集合视图上迭代时,必须在返回的映射上手动同步:…
互斥体确实是“this”,它的编写方式只是习惯用法。同步映射以进行迭代可以正常工作。在互斥体上同步代码而不是直接在此
上同步代码的原因是代码与SynchronizedSortedMap
共享,并且需要支持返回在父映射上同步的子映射。请参见Collections.SynchronizedSortedMap.subMap
@SotiriosDelimanolis我知道,我只是说明为什么这些方法没有被写为public synchronized someMethod…
。这不仅仅是惯用用法,它是为了支持通过SynchronizedMap的第二个构造函数返回在父映射上同步的SynchronizedMap。
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {
return new SynchronizedMap<>(m);
}