Нет, при этом вы теряете преимущества ConcurrentHashMap
. С таким же успехом вы можете использовать HashMap
с synchronized
или synchronizedMap()
для блокировки всей таблицы (что вы и делаете, когда заключаете операции в synchronized
, поскольку подразумевается, что монитор представляет собой экземпляр всего объекта).
Цель ConcurrentHashMap
состоит в том, чтобы увеличить пропускную способность вашего параллельного кода, разрешив одновременное чтение/запись таблицы без блокировки всей таблицы. Таблица поддерживает это внутренне, используя чередование блокировок (несколько блокировок вместо одной, при этом каждая блокировка назначается набору сегментов хеширования — см. Java Concurrency на практике, автор Goetz et al.).
Как только вы используете ConcurrentHashMap
, все стандартные методы карты (put()
, remove()
и т. д.) становятся атомарными благодаря чередованию блокировок и т. д. в реализации. Единственным компромиссом является то, что такие методы, как size()
и isEmpty()
, могут не обязательно возвращать точные результаты, поскольку единственный способ, которым они могли бы, заключался в том, чтобы все операции блокировали всю таблицу.
Интерфейс ConcurrentMap
interface также добавляет новые атомарные составные операции, такие как putIfAbsent()
(поместить что-то, только если ключ еще не находится на карте), remove()
принимать как ключ, так и значение (удалить запись, только если ее значение равно параметру, который вы передаете) и т. д. Раньше эти операции требовали блокировки всей таблицы, потому что они для выполнения требовалось два вызова метода (например, для putIfAbsent()
потребовались бы вызовы как containsKey()
, так и put()
, заключенные в один блок synchronized
, если бы вы использовали стандартную реализацию Map
). Опять же, вы получаете большую пропускную способность, используя эти методы, избегая блокировки всего стол.
person
sparc_spread
schedule
23.09.2014