是否需要将ConcurrentHashMap包装在同步块中?
在ConcurrentHashMap( put()
, remove()
等)上的所有非retreival操作是否需要包装在synchronized(this)
块中? 我知道所有这些操作都是线程安全的,所以这样做有什么好处/需要吗? 使用的唯一操作是put()
和remove()
。
protected final Map mapDataStore = new ConcurrentHashMap(); public void updateDataStore(final String key, final String value) { ... synchronized (this) { mapDataStore.put(key, value); } ... }
不,你这样做会失去ConcurrentHashMap
的好处。 您也可以使用带有synchronized
或synchronizedMap()
的HashMap
来锁定整个表(这是在synchronized
包装操作时所执行的操作,因为监视器隐含的是整个对象实例。)
ConcurrentHashMap
的目的是通过允许对表进行并发读/写而不锁定整个表来增加并发代码的吞吐量。 该表通过使用锁定条带内部支持这一点(多个锁而不是一个,每个锁分配给一组散列桶 – 参见Goetz等人的Java Concurrency in Practice )。
一旦使用ConcurrentHashMap
,所有标准的map方法( put()
, remove()
等)都会因为实现中的锁条带等而变为primefaces。 唯一的权衡是像size()
和isEmpty()
这样的方法可能不一定返回准确的结果,因为它们可能是所有操作锁定整个表的唯一方法。
ConcurrentMap
接口接口还添加了新的primefaces复合操作,如putIfAbsent()
(仅当键不在映射中时才放置东西), remove()
接受键和值(仅当条目的值等于参数时才删除条目)这些操作过去需要锁定整个表,因为它们需要两个方法调用才能完成(例如putIfAbsent()
需要调用containsKey()
和put()
,包含在一个synchronized
块中,如果你使用的话一个标准的Map
实现。)再次,通过避免锁定整个表,您可以使用这些方法获得更大的吞吐量。
同步这些操作在这里没有任何好处 – 如果您不需要同步,它实际上会降低性能。
创建ConcurrentHashMap
的原因是,同步映射(在问题中手动实现或者以通常的方式使用Collections.synchronizedMap(map)
实例化)在许multithreading访问时显示不良性能。 Put和get操作是阻塞的,因此所有其他线程必须等待并且不能同时访问映射。 ConcurrentHashMap
– 顾名思义 – 允许并发访问。 如果添加同步,则会失去此优势。
- 最快的方法来初始化ConcurrentHashMap的值
- 在ConcurrentHashMap中修改值的首选方法是什么?
- ConcurrentHashMap中的分段
- 锁定任意键的处理程序
- ConcurrentHashMap.get()是否保证通过不同的线程看到以前的ConcurrentHashMap.put()?
- 使用java ConcurrentHashMap实现缓存
- 如何使用LinkedHashMap中的类似function实现ConcurrentHashMap?
- 从理论上讲,ConcurrentHashMap的Segment和HashMap的桶之间有什么区别?
- ConcurrentHashMap崩溃使用JDK 8编译但是以JRE 7为目标的应用程序