Hashmap и hashtable в многопоточной среде - PullRequest
6 голосов
/ 01 сентября 2009

Я действительно смущен тем, как эти две коллекции ведут себя в многопоточной среде.

Хеш-таблица синхронизирована, что означает, что никакие 2 потока не будут обновлять свое значение одновременно, верно?

Ответы [ 5 ]

12 голосов
/ 01 сентября 2009

Посмотрите на ConcurrentHashMap s для Потокобезопасных Карт.

Они предлагают все функции HashTable с производительностью, очень близкой к HashMap.

Производительность достигается за счет того, что вместо использования широкой блокировки карты коллекция поддерживает по умолчанию список из 16 блокировок, каждая из которых используется для блокировки одного сегмента карты. Вы даже можете настроить количество сегментов :). Настройка может помочь производительности в зависимости от ваших данных.

Я не могу рекомендовать достаточно параллелизма Java на практике Брайана Гетца http://jcip.net/

Я все еще узнаю что-то новое каждый раз, когда читаю.

3 голосов
/ 01 сентября 2009

Также обратите внимание, что Hashtable и Collections.synchronizedMap безопасны только для отдельных операций. Любые операции с несколькими ключами или проверка-то-действие, которые должны быть атомарными, будут , а не , и потребуется дополнительная блокировка на стороне клиента.

Например, вы не можете написать ни один из следующих методов без дополнительной блокировки:

  • поменяйте местами значения двумя разными клавишами: swapValues(Map, Object k1, Object k2)

  • добавить параметр к значению с помощью клавиши: appendToValue(Map, Object k1, String suffix)

И да, все это описано в JCIP: -)

2 голосов
/ 01 сентября 2009

Точно, HashTable синхронизируется, что означает, что его можно безопасно использовать в многопоточной среде (многие потоки обращаются к одному и тому же HashTable). Если два потока пытаются обновить хеш-таблицу одновременно, одному из них придется ждать, пока другой поток заканчивает свое обновление.

HashMap не синхронизируется, поэтому он быстрее, но у вас могут возникнуть проблемы в многопоточной среде.

0 голосов
/ 01 сентября 2009

Хеш-таблицы синхронизированы, но это старая реализация, которую можно было бы сказать, что она устарела. Кроме того, они не допускают нулевые ключи (может быть, также не нулевые значения? Не уверен).

Одна проблема заключается в том, что, хотя каждый вызов метода синхронизирован, наиболее интересные действия требуют более одного вызова, поэтому вам нужно синхронизировать несколько вызовов.

Подобный уровень синхронизации можно получить для HashMaps, вызвав:

Map m = Collections.synchronizedMap(new HashMap());

, который оборачивает карту в синхронизированные вызовы методов. Но это имеет те же недостатки параллелизма, что и Hashtable.

Как говорит Пол, ConcurrentHashMaps предоставляют потокобезопасные карты с дополнительными полезными методами для атомарных обновлений.

0 голосов
/ 01 сентября 2009

Да, все методы выполняются атомарно, но метод values ​​() - нет (см. docs ).

Пол быстрее меня порекомендовал вам пакет java.util.concurrent, который дает вам очень хороший контроль и структуры данных для многопоточных сред.

...