В чем разница между использованием класса-обёртки SynchronizedMap
, а HashMap
и ConcurrentHashMap
?
Это просто возможность изменить HashMap
время итерации ( ConcurrentHashMap
)?
В чем разница между использованием класса-обёртки SynchronizedMap
, а HashMap
и ConcurrentHashMap
?
Это просто возможность изменить HashMap
время итерации ( ConcurrentHashMap
)?
Ответы:
Синхронизировано HashMap
:
Каждый метод синхронизируется с помощью блокировки уровня объекта. Таким образом, методы get и put для synchMap получают блокировку.
Блокировка всей коллекции - накладные расходы. Пока один поток удерживает блокировку, другой поток не может использовать коллекцию.
ConcurrentHashMap
был введен в JDK 5.
На уровне объекта блокировки нет, Блокировка гораздо более детализирована. Для a ConcurrentHashMap
блокировки могут быть на уровне сегмента hashmap.
Эффект низкоуровневой блокировки заключается в том, что у вас могут быть одновременные программы чтения и записи, что невозможно для синхронизированных коллекций. Это приводит к гораздо большей масштабируемости.
ConcurrentHashMap
не выдает, ConcurrentModificationException
если один поток пытается изменить его, в то время как другой перебирает его.
Эта статья Java 7: HashMap vs ConcurrentHashMap очень хорошо читается. Настоятельно рекомендуется.
ConcurrentHashMap
«S size()
результат может устареть. size()
разрешено возвращать приближение вместо точного подсчета в соответствии с книгой "Java Concurrency in Practice". Поэтому этот метод следует использовать осторожно.
Краткий ответ:
Обе карты являются поточно-ориентированными реализациями Map
интерфейса. ConcurrentHashMap
реализован для более высокой пропускной способности в случаях, когда ожидается высокий параллелизм.
Статья Брайана Гетца об этой идее ConcurrentHashMap
очень хорошо читается. Настоятельно рекомендуется.
Map m = Collections.synchronizedMap(new HashMap(...));
docs.oracle.com/javase/7/docs/api/java/util/HashMap.html
ConcurrentHashMap
является потокобезопасным без синхронизации всей карты. Чтение может происходить очень быстро, в то время как запись выполняется с блокировкой.
Мы можем обеспечить безопасность потоков, используя как ConcurrentHashMap, так и synchronizedHashmap. Но есть большая разница, если вы посмотрите на их архитектуру.
Он будет поддерживать блокировку на уровне объекта. Поэтому, если вы хотите выполнить какую-либо операцию, такую как put / get, вам нужно сначала получить блокировку. В то же время другим потокам не разрешается выполнять какие-либо операции. Таким образом, только один поток может работать с этим. Так что время ожидания здесь увеличится. Можно сказать, что производительность относительно низкая, если сравнивать с ConcurrentHashMap.
Он будет поддерживать блокировку на уровне сегмента. Он имеет 16 сегментов и поддерживает уровень параллелизма как 16 по умолчанию. Таким образом, одновременно 16 потоков могут работать с ConcurrentHashMap. Более того, операция чтения не требует блокировки. Таким образом, любое количество потоков может выполнить операцию get.
Если thread1 хочет выполнить операцию put в сегменте 2, а thread2 хочет выполнить операцию put в сегменте 4, то это разрешено здесь. Значит, 16 потоков могут одновременно выполнять операцию обновления (вставки / удаления) в ConcurrentHashMap.
Так что время ожидания здесь будет меньше. Следовательно, производительность относительно лучше, чем synchronizedHashmap.
Оба являются синхронизированной версией HashMap, с разницей в их основной функциональности и внутренней структуре.
ConcurrentHashMap состоит из внутренних сегментов, которые концептуально можно рассматривать как независимые HashMaps. Все такие сегменты могут быть заблокированы отдельными потоками при одновременном выполнении. Таким образом, несколько потоков могут получать / помещать пары ключ-значение из ConcurrentHashMap, не блокируя и не ожидая друг друга. Это реализовано для повышения пропускной способности.
в то время как
Collections.synchronizedMap () , мы получаем синхронизированную версию HashMap, доступ к которой осуществляется блокирующим образом. Это означает, что если несколько потоков попытаются получить доступ к synchronizedMap одновременно, им будет разрешено получать / помещать пары ключ-значение по одной синхронно.
ConcurrentHashMap
использует более точный механизм блокировки, известный как lock stripping
обеспечивающий большую степень общего доступа. Благодаря этому он обеспечивает лучший параллелизм и масштабируемость .
Кроме того, возвращаемые значения для итераторов ConcurrentHashMap
являются слабосогласованными вместо метода быстрого отказа, используемого Synchronized HashMap.
Методы SynchronizedMap
удерживают блокировку на объекте, в то время как ConcurrentHashMap
есть понятие «чередование блокировок», когда вместо блокировок удерживаются блоки содержимого. Таким образом улучшается масштабируемость и производительность.
ConcurrentHashMap:
1) Обе карты являются поточно-ориентированными реализациями интерфейса Map.
2) ConcurrentHashMap реализован для более высокой пропускной способности в тех случаях, когда ожидается высокий параллелизм.
3) Нет блокировки на уровне объекта.
Синхронизированная карта хеша:
1) Каждый метод синхронизируется с помощью блокировки уровня объекта.
ConcurrentHashMap обеспечивает одновременный доступ к данным. Вся карта делится на сегменты.
Операция чтения т.е. get(Object key)
не синхронизируется даже на уровне сегмента.
Но операции записи т.е. remove(Object key), get(Object key)
получить блокировку на уровне сегмента. Только часть всей карты заблокирована, другие потоки все еще могут читать значения из различных сегментов, кроме заблокированного.
SynchronizedMap, с другой стороны, получает блокировку на уровне объекта. Все потоки должны ждать текущего потока независимо от операции (чтение / запись).
Простой тест производительности для ConcurrentHashMap против Synchronized HashMap
. Тестовый поток вызывает put
в одном потоке и одновременно get
в трех потоках Map
. Как сказал @trshiv, ConcurrentHashMap имеет более высокую пропускную способность и скорость для операций чтения без блокировки. В результате, когда время работы истекло 10^7
, ConcurrentHashMap работает 2x
быстрее, чем Synchronized HashMap.
SynchronizedMap
и ConcurrentHashMap
оба поточно класса и могут быть использованы в многопоточном приложении, основное различие между ними относительно того, как они достигают безопасности потока.
SynchronizedMap
получает блокировку для всего экземпляра Map, в то время ConcurrentHashMap
как экземпляр Map разделяется на несколько сегментов, и блокировка выполняется для них.
Согласно документу Java
Hashtable и Collections.synchronizedMap (новый HashMap ()) синхронизируются. Но ConcurrentHashMap является «одновременным».
Параллельная коллекция является поточно-ориентированной, но не управляется одной блокировкой исключения.
В конкретном случае ConcurrentHashMap он безопасно разрешает любое количество одновременных операций чтения, а также настраиваемое количество одновременных операций записи. «Синхронизированные» классы могут быть полезны, когда вам нужно запретить любой доступ к коллекции через одну блокировку за счет более низкой масштабируемости.
В других случаях, когда ожидается, что несколько потоков получат доступ к общей коллекции, «параллельные» версии обычно предпочтительнее. А несинхронизированные коллекции предпочтительнее, когда либо коллекции не являются общими, либо доступны только при удержании других блокировок.
Hashtable
иSynchronized HashMap
?