Является ли java.util.Hashtable поток безопасным? - PullRequest
7 голосов
/ 13 сентября 2011

Прошло много времени с тех пор, как я использовал hashtable для чего-то значительного, но я, кажется, вспоминаю синхронизацию методов get () и put ().

JavaDocs не отражают это. Они просто говорят, что класс Hashtable синхронизирован. Что я могу предположить? Если несколько потоков обращаются к хеш-таблице одновременно (при условии, что они не изменяют одну и ту же запись), операции завершатся успешно, верно? Я предполагаю, что я спрашиваю: «Является ли поток java.util.Hashtable безопасным?»

Пожалуйста, помогите мне выйти из этого вопроса ...

Ответы [ 9 ]

12 голосов
/ 13 сентября 2011

Это потокобезопасно, потому что методы get, put, содержит методы и т. Д. Синхронизированы.Кроме того, несколько потоков не смогут получить доступ к хеш-таблице одновременно, независимо от того, какие записи они изменяют.

edit - дополнено условием, что синхронизация делает хеш-таблицу внутренне поточной безопасностью, поскольку она модифицируетсяатомарный;он не защищает от состояния гонки во внешнем коде, вызванного одновременным доступом к хеш-таблице несколькими потоками.

10 голосов
/ 13 сентября 2011

Для общего использования это потокобезопасно.

Но вы должны понимать, что это делает вашу логику приложения поточно-ориентированной.Например, рассмотрите возможность реализации, чтобы поместить значение в карту, если его там еще нет.Эта идиома называется putIfAbsent.Это сложно реализовать поточно-ориентированным способом, используя только HashTable.Аналогично для идиомы заменить (k, V, V).

Следовательно для некоторых идиом, таких как putIfAbsent и и заменить (K, V, V) , ярекомендуем использовать ConcurrentHashMap

3 голосов
/ 13 сентября 2011

Hashtable устарела.Забудь это.Если вы хотите использовать синхронизированные коллекции, используйте для этой цели оболочку Collections.syncrhonize * ().Но эти не рекомендуется.В Java 5 реализовано 6 новых параллельных алгоритмов.Копирование при записи, CAS, алгоритмы без блокировки.Для интерфейса Map есть две параллельные реализации.ConcurrentHashMap (одновременная карта хеша) и ConcurrentSkipListMap - реализация одновременно отсортированной карты.

Первая оптимизирована для чтения, поэтому извлечения не блокируются даже во время обновления таблицы.Запись также работает намного быстрее по сравнению с синхронизированными оболочками, потому что ConcurrentHashMap состоит не из одной, а из набора таблиц, называемых сегментами.Им можно управлять с помощью последнего аргумента в конструкторе:

public ConcurrentHashMap(int initialCapacity,
                         float loadFactor,
                         int concurrencyLevel);

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

2 голосов
/ 13 сентября 2011

Я спрашиваю: "Является ли поток java.util.Hashtable безопасным?"через HashMap. В случае, если желательна поточно-ориентированная реализация, рекомендуется использовать ConcurrentHashMap вместо Hashtable.

1 голос
/ 13 сентября 2011

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

Даже перебор записей Hashtable не безопасен для потоков, если толькоВы также защищаете Карту от изменения с помощью дополнительной синхронизации.

1 голос
/ 13 сентября 2011

Нет. «Потокобезопасен» только в той степени, в которой его методы синхронизированы. Однако он не является потокобезопасным в целом и не может быть, потому что классы, экспортирующие внутреннее состояние, такие как Итераторы или Перечисления, также требуют синхронизации внутреннего состояния. Вот почему новые классы коллекций не синхронизированы, так как дизайнеры Java признали, что безопасность потоков зависит от пользователя класса, а не от самого класса.

0 голосов
/ 07 ноября 2013

В отличие от новых реализаций коллекции, Hashtable синхронизируется. * Если поточно-ориентированная реализация не требуется, рекомендуется использовать HashMap * вместо Hashtable. Если требуется потокобезопасная высококонкурентная реализация , то рекомендуется использовать ConcurrentHashMap вместо Hashtable.

http://download.oracle.com/javase/7/docs/api/java/util/Hashtable.html

0 голосов
/ 17 апреля 2013

Если вы посмотрите на код Hashtable, вы увидите, что методы синхронизированы, такие как:

public synchronized V get(Object key) 
 public synchronized V put(K key, V value)
 public synchronized boolean containsKey(Object key)

Вы можете продолжать нажимать клавишу управления (команда для Mac), а затем нажать на любое имя метода взатмение, чтобы перейти к исходному коду Java.

0 голосов
/ 13 сентября 2011

Да, поток Hashtable безопасен, поэтому только один поток может получить доступ к хэш-таблице в любое время.

HashMap, с другой стороны, не является потокобезопасным (и, следовательно, «быстрее»).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...