是否需要将ConcurrentHashMap包装在同步块中? [英] Does a ConcurrentHashMap need to be wrapped in a synchronized block?

查看:131
本文介绍了是否需要将ConcurrentHashMap包装在同步块中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对ConcurrentHashMap进行所有非retreival操作( put() remove()等)需要被包装在 synchronized(this)块中?我知道所有这些操作都是线程安全的,所以这样做有什么好处/需要吗?使用的唯一操作是 put() remove()

Do all non-retreival operations on a ConcurrentHashMap (put(), remove() etc.) need to be wrapped in a synchronized(this) block? I understand that all of these operations are thread-safe, so is there any real benefit/need in doing so? The only operations used are put() and remove().

protected final Map<String, String> mapDataStore = new ConcurrentHashMap<String, String>();

public void updateDataStore(final String key, final String value) {
    ...
    synchronized (this) {
        mapDataStore.put(key, value);
    }
    ...
}


推荐答案

不,你这样做会失去 ConcurrentHashMap 的好处。您也可以使用 HashMap synchronized synchronizedMap()锁定整个表(这是在 synchronized 中包装操作时所执行的操作,因为监视器隐含的是整个对象实例。)

No, you are losing the benefits of ConcurrentHashMap by doing that. You may as well be using a HashMap with synchronized or synchronizedMap() to lock the whole table (which is what you do when wrapping operations in synchronized, since the monitor implied is the entire object instance.)

ConcurrentHashMap 的目的是通过允许对表进行并发读/写而不锁定整个表来增加并发代码的吞吐量。该表通过使用锁定条带内部支持这一点(多个锁而不是一个,每个锁分配给一组散列桶 - 参见 Java Concurrency in Practice

The purpose of ConcurrentHashMap is to increase the throughput of your concurrent code by allowing concurrent read/writes on the table without locking the entire table. The table supports this internally by using lock striping (multiple locks instead of one, with each lock assigned to a set of hash buckets - see Java Concurrency in Practice by Goetz et al).

一旦使用 ConcurrentHashMap ,所有标准地图方法( put() remove()等)由于实现中的锁条带等而变为原子。唯一的权衡是像 size()这样的方法isEmpty()可能不一定会返回准确的结果,因为只有它们可以用于所有操作来锁定整个表格。

Once you are using ConcurrentHashMap, all standard map methods (put(), remove(), etc.) become atomic by virtue of the lock striping etc. in the implementation. The only tradeoffs are that methods like size() and isEmpty() may not necessarily return accurate results, since the only way they could would be for all operations to lock the whole table.

ConcurrentMap interface 接口还添加了新的原子复合操作,如 putIfAbsent() (只有当密钥不在地图中时才放置东西), remove()同时接受密钥和值(仅当删除条目时才删除它的值等于你传递的参数,等等。这些操作过去需要锁定整个表,因为它们需要两个方法调用来完成(例如 putIfAbsent()需要调用两个 containsKey() put(),包含在一个 synchronized 阻止,如果你使用的是标准的 Map 实现。)再一次,你获得更大的收益通过避免锁定整个表来使用这些方法进行输出。

The ConcurrentMap interface interface also adds new atomic compound operations like putIfAbsent() (put something only if it the key is not already in the map), remove() accepting both key and value (remove an entry only if its value equals a parameter you pass), etc. These operations used to require locking the whole table because they needed two method calls to accomplish (e.g. putIfAbsent() would need calls to both containsKey() and put(), wrapped inside one synchronized block, if you were using a standard Map implementation.) Once again, you gain greater throughput using these methods, by avoiding locking the entire table.

这篇关于是否需要将ConcurrentHashMap包装在同步块中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆