Разница между блокировкой в Collections.synchronizedMap()
и ConcurrentHashMap
заключается в следующем:
Если несколько потоков будут обращаться к Collections.synchronizedMap()
часто, возникнет много конфликтов, поскольку каждый метод синхронизируется с использованием общей блокировки (т. Е. Если поток X вызывает метод на Collections.synchronizedMap()
, все другие потоки будут заблокированы от вызова любого метода на Collections.synchronizedMap()
пока поток X не вернется из вызванного им метода).
ConcurrentHashMap
имеет переменное количество блокировок (по умолчанию 16), каждая из которых защищает сегмент ключей в ConcurrentHashMap
. Таким образом, для ConcurrentHashMap
со 160 ключами каждый замок будет защищать 10 элементов. Следовательно, методы, работающие с ключом (get
, put
, set
и т. Д.), Блокируют доступ только к другим методам, работающим с ключом, ключи которого находятся в том же сегменте. Например, если поток X вызывает put(0, someObject)
, а затем поток Y вызывает put(10, someOtherObject)
, эти вызовы могут выполняться одновременно, и потоку Y не нужно ждать, пока поток X вернется из put(0, someObject)
. Пример приведен ниже.
Кроме того, некоторые методы, такие как size()
и isEmpty()
, вообще не защищены. Хотя это обеспечивает больший параллелизм, это означает, что они не являются строго согласованными (они не отражают состояние, которое одновременно изменяется).
public static void main(String[] args) {
ConcurrentHashMap<Integer, Object> map = new ConcurrentHashMap<>(160);
new Thread(new Runnable() {
@Override
public void run() {
map.put(0, "guarded by one lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
map.put(10, "guarded by another lock");
}
}.start();
new Thread(new Runnable() {
@Override
public void run() {
// could print 0, 1, or 2
System.out.println(map.count());
}
}.start();
}
person
ashish_388235
schedule
22.04.2013