Подтвердить что ты не робот

ConcurrentHashMap в Java?

Каково использование ConcurrentHashMap в Java? Каковы его преимущества? Как это работает? Пример кода также будет полезен.

4b9b3361

Ответ 1

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

Еще одна особенность ConcurrentHashMap заключается в том, что она предоставляет метод putIfAbsent, который будет атомарно добавлять отображение, если указанный ключ не существует. Рассмотрим следующий код:

ConcurrentHashMap<String, Integer> myMap = new ConcurrentHashMap<String, Integer>();

// some stuff

if (!myMap.contains("key")) {
  myMap.put("key", 3);
}

Этот код не является потокобезопасным, потому что другой поток может добавить сопоставление для "key" между вызовом contains и вызовом put. Правильная реализация:

myMap.putIfAbsent("key", 3);

Ответ 2

ConcurrentHashMap разрешить одновременный доступ к карте. HashTables также предлагает синхронизированный доступ к карте, но вся ваша карта заблокирована для выполнения любой операции.

Логикой ConcurrentHashMap является your entire table is not getting locked, но только часть [segments]. Каждый сегмент управляет собственным HashTable. Блокировка применяется только для обновлений. В случае изъятий он позволяет использовать полный concurrency.

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

enter image description here

Это эффективно означает, что 16 потоков могут изменять коллекцию за один раз. Этот уровень concurrency можно увеличить, используя необязательный аргумент concurrencyLevel constructor.

public ConcurrentHashMap(int initialCapacity,
                         float loadFactor, int concurrencyLevel)

Как сказал другой ответ, ConcurrentHashMap предлагает новый метод putIfAbsent(), который похож на put, за исключением того, что значение не будет переопределено, если ключ существует.

private static Map<String,String> aMap =new ConcurrentHashMap<String,String>();

if(!aMap.contains("key"))
   aMap.put("key","value");

Новый метод также быстрее, поскольку он избегает double traversing, как указано выше. contains метод должен найти сегмент и перебрать таблицу, чтобы найти ключ, и снова метод put должен пересечь ведро и поместить ключ.

Ответ 3

Действительно, большая функциональная разница заключается в том, что она не генерирует исключение и/или не повреждается, когда кто-то другой меняет его, пока вы его используете.

С регулярными коллекциями, если другой поток добавляет или удаляет элемент во время доступа к нему (через итератор), он генерирует исключение. ConcurrentHashMap позволяет им вносить изменения и не останавливать поток.

Имейте в виду, что он не предоставляет никаких гарантий синхронизации или promises о видимости изменения времени от одного потока к другому. (Это похоже на изоляцию данных с защитой от чтения, а не на синхронизированную карту, которая ведет себя скорее как сериализуемая изоляция базы данных (старая школьная строка-блокировка SQL-сериализуемая, а не Oracle-ish multiversion serializable:))

Наиболее распространенное использование, о котором я знаю, заключается в кешировании неизменяемой производной информации в средах App Server, где многие потоки могут получать доступ к одной и той же вещи, и на самом деле не имеет значения, могут ли два вычислить одно и то же значение кеша и дважды добавить его потому что они чередуются и т.д. (например, он широко используется внутри среды Spring WebMVC для хранения конфигурации, зависящей от времени выполнения, например сопоставления URL-адресов с методами Handler.)

Ответ 4

Его можно использовать для memoization:

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));
};

Ответ 5

1.ConcurrentHashMap является потокобезопасным, к коду может обращаться один поток за раз.

2.ConcurrentHashMap синхронизирует или блокирует определенную часть Карты. Чтобы оптимизировать производительность ConcurrentHashMap, карта делится на разные разделы в зависимости от уровня Concurrency. Так что нам не нужно синхронизировать весь объект карты.

Уровень 3.Default Concurrency равен 16, соответственно карта делится на 16 частей, и каждая часть управляется с помощью другой блокировки, которая может работать с 16 потоками.

4.ConcurrentHashMap не разрешает значения NULL. Таким образом, ключ не может быть пустым в ConcurrentHashMap.

Ответ 6

Привет, ребята, сегодня мы обсуждали ConcurrentHashMap.
Что такое ConcurrentHashMap?

ConcurrentHashMap - это класс, представленный в Java 1.5, который реализует ConcurrentMap, а также интерфейс Serializable. ConcurrentHashMap улучшает HashMap, когда имеет дело с несколькими Theading. Как мы знаем, когда приложение имеет многопоточность, HashMap не является хорошим выбором, потому что возникла проблема с производительностью.

Есть некоторая ключевая точка ConcurrentHashMap.

  • Базовая структура данных для ConcurrentHashMap - HashTable.
  • ConcurrentHashMap - это класс. Этот класс является потокобезопасным, это означает, что несколько потоков могут обращаться к одному объекту потока без каких-либо сложностей.
  • Объект ConcurretnHashMap делится на количество сегментов в соответствии с уровнем параллелизма.
  • Уровень параллелизма по умолчанию для ConcurrentHashMap - 16.
  • В ConcurrentHashMap любое количество Thread может выполнить операцию поиска, но для обновления в объекте Thread необходимо заблокировать тот сегмент, в котором поток хочет работать.
  • Этот тип механизма блокировки известен как блокировка сегмента или блокировка сегмента.
  • В ConcurrentHashMap 16 операций обновления выполняются одновременно.
  • Нулевая вставка невозможна в ConcurrentHashMap.

Вот конструкция ConcurrentHashMap.

  1. ConcurrentHashMap m = new ConcurrentHashMap() ;: Создает новую пустую карту с начальной емкостью по умолчанию (16), коэффициентом загрузки (0,75) и concurrencyLevel (16).

  2. ConcurrentHashMap m = new ConcurrentHashMap (int initialCapacity) ;: Создает новую пустую карту с указанной начальной емкостью, с коэффициентом загрузки по умолчанию (0,75) и concurrencyLevel (16).

  3. ConcurrentHashMap m = new ConcurrentHashMap (int initialCapacity, float loadFactor) ;: Создает новую пустую карту с указанной начальной емкостью и коэффициентом загрузки и с параметром concurrencyLevel по умолчанию (16).

  4. ConcurrentHashMap m = новый ConcurrentHashMap (int initialCapacity, float loadFactor, int concurrencyLevel) ;: создает новую пустую карту с указанными начальной емкостью, коэффициентом загрузки и уровнем параллелизма.

  5. ConcurrentHashMap m = new ConcurrentHashMap (Map m) ;: Создает новую карту с теми же отображениями, что и для данной карты.

В ConcurretHashMap есть один метод с именем putIfAbsent(); Этот метод не позволяет сохранить дубликат ключа, см. Пример ниже.

    import java.util.concurrent.*; 

     class ConcurrentHashMapDemo { 
     public static void main(String[] args) 
     { 
         ConcurrentHashMap m = new ConcurrentHashMap(); 
          m.put(1, "Hello"); 
          m.put(2, "Vala"); 
          m.put(3, "Sarakar"); 

         // Here we cant add Hello because 1 key 
         // is already present in ConcurrentHashMap object 

            m.putIfAbsent(1, "Hello"); 

         // We can remove entry because 2 key 
         // is associated with For value 

            m.remove(2, "Vala"); 

        // Now we can add Vala

            m.putIfAbsent(4, "Vala"); 


            System.out.println(m); 
      } 
}