ConcurrentHashMap, который улучшил параллельные функции в JDK8


Может ли любой параллельный эксперт объяснить в ConcurrentHashMap, какие параллельные функции улучшились по сравнению с предыдущими JDKs

2 8

2 ответа:

Ну, ConcurrentHashMap был полностью переписан. До Java 8 каждый ConcurrentHashMap имел "уровень параллелизма", который был зафиксирован во время построения. По соображениям совместимости, все еще существует конструктор , принимающий такой уровень, хотя и не использующий его оригинальным способом. Карта была разделена на столько сегментов, сколько ее уровень параллелизма, каждый из которых имел свою собственную блокировку, поэтому теоретически могло быть до уровня параллелизма одновременных обновлений, если бы все они были нацелены на разные сегменты, которые зависят от хеширования.

В Java 8 каждый хэш-бакет может обновляться по отдельности, поэтому, пока нет коллизий хэша, может быть столько одновременных обновлений, сколько его текущая емкость. Это соответствует новым функциям, таким как compute методы, которые гарантируют атомарные обновления, следовательно, блокировку по крайней мере хэш-ведра, которое обновляется. В лучшем случае они действительно запирают только одно ведро.

Далее, ConcurrentHashMap извлекает выгоду из общие улучшения хэша применяются ко всем видам хэш-карт. При наличии хэш-коллизий для определенного ведра реализация будет использовать сортированную структуру типа карты внутри этого ведра, таким образом, деградируя до сложности O(log(n)), а не до сложности O(n) старой реализации при поиске ведра.

Я думаю, что есть несколько изменений по сравнению с JDK7:

  • ленивая инициализация: в JDK8 память, используемая для каждого сегмента, выделяется только при добавлении некоторого объекта на карту. В JDK7 это делается при создании карты.
  • в JDK8 добавлена новая функция, например forEach, reduce, search и т. д.
  • изменение внутренней структуры: TreeBin (красно-черное дерево) используется в jdk8 для повышения эффективности поиска.