Что такое использование ConcurrentHashMap
в Java? Каковы его преимущества? Как это работает? Пример кода тоже полезен.ConcurrentHashMap в Java?
ответ
Дело в том, чтобы обеспечить реализацию HashMap
, которая является потокобезопасной. Несколько потоков могут читать и записывать на него без возможности получения устаревших или поврежденных данных. ConcurrentHashMap
обеспечивает собственную синхронизацию, поэтому вам не нужно синхронизировать доступ к ней явно.
Другой особенностью ConcurrentHashMap
является то, что она обеспечивает putIfAbsent
метод, который будет атомарно добавить отображение, если указанный ключ не существует. Рассмотрим следующий код:
ConcurrentHashMap<String, Integer> myMap = new ConcurrentHashMap<String, Integer>();
// some stuff
if (!myMap.contains("key")) {
myMap.put("key", 3);
}
Этот код не THREADSAFE, потому что другой поток может добавить отображение для "key"
между вызовом contains
и призыв к put
. Правильная реализация будет:
myMap.putIfAbsent("key", 3);
Я бы описал это скорее как «безопасно несинхронизированный». Это позволяет двум потокам быть в то же время и одновременно обещать закончить в последовательном состоянии. – Affe
Синхронизация не является (внешней) гарантией заказа. – danben
Это не гарантия того, что потоки, запрашивающие монитор, получат его в запрошенном порядке, но прежде чем гарантировать, что когда один поток обретает монитор и начинает изменять карту, никто другой не увидит его, пока модификация не будет сделанный. В параллельной карте один поток может начать ставить, а затем не планировать снова в течение долгого времени, а другие потоки могут выполнять запросы, которые не будут отображаться. – Affe
Действительно большая функциональная разница в том, что не бросает исключение, и/или в конечном итоге коррумпированный, когда кто-то изменяет его в то время как вы используете его.
С регулярными коллекциями, если другой поток добавляет или удаляет элемент во время доступа к нему (через итератор), он генерирует исключение. ConcurrentHashMap позволяет им вносить изменения и не останавливает поток.
Имейте в виду, что он не гарантирует каких-либо гарантий синхронизации или обещаний о видимости момента времени от одного потока к другому. (Это похоже на изоляцию данных с защитой от чтения, а не на синхронизированную карту, которая больше похожа на сериализуемую изоляцию базы данных. (Old school row-locking SQL serializable, а не Oracle-ish multiversion serializable :))
общее использование, которое я знаю, заключается в кешировании неизменяемой производной информации в средах App Server, где многие потоки могут обращаться к одной и той же вещи, и не имеет большого значения, если два из них будут вычислять одно и то же значение кеша и помещать его дважды, потому что они чередуются и т. д. (например, он широко используется внутри среды Spring WebMVC для хранения конфигурации, связанной с исполняемой средой, например сопоставлений с URL-адресами для методов Handler.)
Это совсем не так. Javadocs явно указывает, что все операции являются потокобезопасными. – danben
Все операции являются потокобезопасными, но до обеда не происходит, как в случае с синхронизированной картой. То, что вы видите, когда вы смотрите в ConcurrentHashMap, является результатом последних завершенных операций. Некоторые из них, возможно, начались значительно позже, чем когда вы начали искать. Он работает скорее как изоляция базы данных с чтением, тогда как синхронизированная карта больше похожа на сериализуемую изоляцию базы данных. – Affe
отличный ответ – SuprF1y
ConcurrentHashMap
Позволяет осуществлять параллельный доступ к карте. HashTables также предлагает синхронизированный доступ к карте, но вся ваша карта заблокирована для выполнения любой операции.
Логика для ConcurrentHashMap заключается в том, что your entire table is not getting locked
, но только часть [segments
]. Каждый сегмент управляет собственным HashTable. Блокировка применяется только для обновлений. В случае извлечения, он позволяет полностью параллелизм.
Давайте возьмем четыре потока одновременно, работая на карте с емкостью 32, таблица разделена на четыре сегмента, где каждый сегмент управляет хэш-таблицей емкости. В коллекции хранится список из 16 сегментов по умолчанию, каждый из которых используется для защиты (или блокировки) одного ведра карты.
Это фактически означает, что 16 потоков могут изменять коллекцию за один раз. Этот уровень параллелизма может быть увеличен с помощью необязательного аргумента concurrencyLevel constructor.
public ConcurrentHashMap(int initialCapacity,
float loadFactor, int concurrencyLevel)
Как заявил другой ответ, то ConcurrentHashMap предлагает новый метод putIfAbsent()
, который похож поставить кроме значения не будет отменен, если ключ существует.
private static Map<String,String> aMap =new ConcurrentHashMap<String,String>();
if(!aMap.contains("key"))
aMap.put("key","value");
Новый метод также быстрее, так как это позволяет избежать double traversing
, как описано выше. contains
метод должен найти сегмент и перебрать таблицу, чтобы найти ключ, и снова метод put
должен пересечь ведро и поместить ключ.
по умолчанию размер 32, тогда как 4 потока могут создать сегмент размера 16. не было бы 8 –
Он может быть использован для запоминания:
import java.util.concurrent.ConcurrentHashMap;
public static Function<Integer, Integer> fib = (n) -> {
Map<Integer, Integer> cache = new ConcurrentHashMap<>();
if (n == 0 || n == 1) return n;
return cache.computeIfAbsent(n, (key) -> HelloWorld.fib.apply(n - 2) + HelloWorld.fib.apply(n - 1));
};
1.ConcurrentHashMap потокобезопасен что код можно получить с помощью одного потока одновременно.
2.ConcurrentHashMap синхронизирует или блокирует определенную часть Карты. Чтобы оптимизировать производительность ConcurrentHashMap, карта делится на разные разделы в зависимости от уровня параллелизма. Так что нам не нужно синхронизировать весь объект Map.
3. Параллельный уровень совместимости 3.Default равен 16, соответственно карта разделена на 16 частей, и каждая часть управляется с помощью другой блокировки, что означает, что 16 потоков могут работать.
4.ConcurrentHashMap не допускает значений NULL. Таким образом, ключ не может быть пустым в ConcurrentHashMap.
- 1. Java ConcurrentHashMap
- 2. Java: ConcurrentHashMap
- 3. Java - ThreadLocal vs ConcurrentHashMap
- 4. Java ConcurrentHashMap и синхронизация
- 5. Проблемы с Java ConcurrentHashmap
- 6. Java ConcurrentHashMap действия atomicity
- 7. Запрос относительно ConcurrentHashMap в Java
- 8. Сортировка значений в Java ConcurrentHashMap
- 9. новый ConcurrentHashMap нового ConcurrentHashMap
- 10. Java ConcurrentHashMap не потокобезопасен .. wth?
- 11. Java: значение ConcurrencyLevel для ConcurrentHashMap
- 12. Шаблон для Java ConcurrentHashMap наборов
- 13. Java ConcurrentHashMap переопределяет все записи
- 14. Вычислить дельта в ConcurrentHashmap в Java
- 15. Transform ConcurrentHashMap в отсортированный список в Java
- 16. Что segmentMask означает в Java ConcurrentHashMap
- 17. Java - Правильный способ добавления ConcurrentHashMap в JList?
- 18. производитель потребительской модели с ConcurrentHashMap в Java
- 19. Недостаток увеличения количества разделов в Java ConcurrentHashMap?
- 20. Java: Использование ConcurrentHashMap в качестве менеджера блокировки
- 21. примеры ConcurrentHashMap
- 22. Перебор ConcurrentHashMap
- 23. Сегментация ConcurrentHashMap
- 24. ConcurrentHashMap операции
- 25. Преобразование ConcurrentHashMap в HashMap
- 26. Java: Как сделать статический снимок ConcurrentHashMap?
- 27. Память Полностью используется Java ConcurrentHashMap (под Tomcat)
- 28. Почему ConcurrentHashMap :: putIfAbsent быстрее, чем ConcurrentHashMap :: computeIfAbsent?
- 29. Java Удалить конкретный элемент из ConcurrentHashMap
- 30. Java ConcurrentHashMap и для каждого цикла
http://javarevisited.blogspot.in/2013/02/concurrenthashmap-in-java-example-tutorial-working.html – roottraveller