Может ли Java HashMap создавать тупики? - PullRequest
2 голосов
/ 22 декабря 2011

У меня есть HashMap, который многие потоки читают и записывают одновременно.

Может ли это вызвать тупик?

Ответы [ 9 ]

4 голосов
/ 22 декабря 2011

Взаимные блокировки возникают, только если вы используете несколько блокировок и не блокируете / разблокируете их в правильном порядке. Если вы защищаете свою HashMap только одной (правильно используемой) блокировкой (или не используете ее вообще), то взаимоблокировки не могут возникнуть.

Обратите внимание, что стандарт HashMap сам по себе никак не защищен, поэтому только ваш код блокировки (который вы не опубликовали) может вызвать взаимоблокировку.

2 голосов
/ 30 июня 2016

Я видел, как HashMap заходил в бесконечные циклы, когда он одновременно изменялся.Он не связан с взаимоблокировкой (или прямой блокировкой), но вызван обходом поврежденной структуры данных.

Это особенно происходит, когда корзина преобразуется в TreeNode, так как код, который пересекает деревья, не защищает себя от неработающих ссылок.

Как правило, вы затем видите трассировки стека, где поток застрял в putTreeVal или похожие места.

2 голосов
/ 22 декабря 2011

Хеш-карта сама по себе не выполняет никакой блокировки. Тем не менее, любой правильный код, который читает и изменяет одну и ту же карту из нескольких потоков, должен будет использовать блокировки. Как только блокировка входит в картину, есть вероятность тупиков.

Не зная больше о том, сколько существует блокировок и как они используются, невозможно точно сказать, возможен ли тупик.

1 голос
/ 22 декабря 2011

тупик невозможен при использовании без украшения HashMap. Класс HashMap не блокирует, поэтому нет возможности для тупика.

Однако, если вы использовали Collections.synchronizedMap(...), чтобы обернуть HashMap, и вы использовали это в сочетании с другими блокировками, вы могли бы зайти в тупик ... если разные потоки получили блокировки на объекты в другом порядке.

И очевидно, что несколько потоков, обращающихся к одному и тому же HashMap (который не является потокобезопасным), опасны. Действительно, может быть в состоянии для одного потока увидеть несогласованное состояние HashMap, которое заставляет его войти в бесконечный цикл; например застрял в видимом цикле в одной из цепочек хешей. Это кажется маловероятным, но, чтобы быть уверенным, что это было невозможно, вам необходимо провести тщательный анализ кода с учетом аномалий памяти, вызванных множественными потоками, попадающими в структуру данных без синхронизации.

1 голос
/ 22 декабря 2011

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

java.util.concurrent.ConcurrentHashMap поточно-ориентирован и обеспечивает хорошую производительностьТем не менее, многопоточность - это намного больше.

1 голос
/ 22 декабря 2011

тупик - это когда 2 актера блокируют и ждут ресурсы друг друга.

Конечно, при использовании HashMap может возникнуть тупик. Но тупик создается вашим кодом, который использует HashMap.

Проверьте ваш код, прошу, ответ в нем.

0 голосов
/ 22 декабря 2011

HashMap не является поточно-ориентированным. Чтобы сделать HashMap поточно-ориентированным, используйте метод Collections.synchronizedMap().

HashMap<K, V> map = Collections.synchronizedMap(new HashMap<K, V>());
0 голосов
/ 22 декабря 2011

Вы действительно имеете в виду тупик или, может быть, бесконечный цикл? При использовании несинхронизированного HashMap в многопоточной среде несколько модификаций могут создать внутренне прерванную структуру хэш-карты. Используйте Collections.synchronizedMap(), чтобы избежать этого.

0 голосов
/ 22 декабря 2011

HashMap не синхронизирован, так что да, вы, вероятно, попадете в беду. Я не уверен, что это именно тупик - полагаю, это будет зависеть от реализации, но вы можете получить недостающую информацию.

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

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