Параллелизм Java - интерфейс ConcurrentMap

Интерфейс java.util.concurrent.ConcurrentMap - это подинтерфейс интерфейса Map, поддерживающий атомарные операции с базовой переменной карты. У него есть методы получения и установки, которые работают как чтение и запись для изменчивых переменных. То есть набор имеет отношение «происходит до» с любым последующим получением той же переменной. Этот интерфейс обеспечивает безопасность потоков и гарантии атомарности.

Методы ConcurrentMap

Sr. No. Метод и описание
1

default V compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Пытается вычислить сопоставление для указанного ключа и его текущего сопоставленного значения (или null, если текущего сопоставления нет).

2

default V computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)

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

3

default V computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

Если значение для указанного ключа присутствует и не равно нулю, пытается вычислить новое сопоставление с учетом ключа и его текущего сопоставленного значения.

4

default void forEach(BiConsumer<? super K,? super V> action)

Выполняет указанное действие для каждой записи на этой карте, пока все записи не будут обработаны или действие не вызовет исключение.

5

default V getOrDefault(Object key, V defaultValue)

Возвращает значение, которому сопоставлен указанный ключ, или defaultValue, если эта карта не содержит сопоставления для ключа.

6

default V merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction)

Если указанный ключ еще не связан со значением или связан с null, связывает его с заданным ненулевым значением.

7

V putIfAbsent(K key, V value)

Если указанный ключ еще не связан со значением, свяжите его с данным значением.

8

boolean remove(Object key, Object value)

Удаляет запись для ключа, только если в настоящее время сопоставлено с заданным значением.

9

V replace(K key, V value)

Заменяет запись для ключа, только если в настоящее время сопоставлено с некоторым значением.

10

boolean replace(K key, V oldValue, V newValue)

Заменяет запись для ключа, только если в настоящее время сопоставлено с заданным значением.

11

default void replaceAll(BiFunction<? super K,? super V,? extends V> function)

Заменяет значение каждой записи результатом вызова данной функции для этой записи до тех пор, пока все записи не будут обработаны или функция не вызовет исключение.

пример

Следующая программа TestThread показывает использование ConcurrentMap и HashMap.

import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class TestThread {

   public static void main(final String[] arguments) {
      Map<String,String> map = new ConcurrentHashMap<String, String>();

      map.put("1", "One");
      map.put("2", "Two");
      map.put("3", "Three");
      map.put("5", "Five");
      map.put("6", "Six");

      System.out.println("Initial ConcurrentHashMap: " + map);
      Iterator<String> iterator = map.keySet().iterator();

      try { 
         
         while(iterator.hasNext()) {
            String key = iterator.next();
            
            if(key.equals("3")) {
               map.put("4", "Four");
            }
         }
      } catch(ConcurrentModificationException cme) {
         cme.printStackTrace();
      }
      System.out.println("ConcurrentHashMap after modification: " + map);

      map = new HashMap<String, String>();

      map.put("1", "One");
      map.put("2", "Two");
      map.put("3", "Three");
      map.put("5", "Five");
      map.put("6", "Six");

      System.out.println("Initial HashMap: " + map);
      iterator = map.keySet().iterator();

      try {
         
         while(iterator.hasNext()) {
            String key = iterator.next();
            
            if(key.equals("3")) {
               map.put("4", "Four");
            }
         }
         System.out.println("HashMap after modification: " + map);
      } catch(ConcurrentModificationException cme) {
         cme.printStackTrace();
      }
   }  
}

Это даст следующий результат.

Вывод

Initial ConcurrentHashMap: {1 = One, 2 = Two, 3 = Three, 5 = Five, 6 = Six}
ConcurrentHashMap after modification: {1 = One, 2 = Two, 3 = Three, 4 = Four, 5 = Five, 6 = Six}
Initial HashMap: {1 = One, 2 = Two, 3 = Three, 5 = Five, 6 = Six}
java.util.ConcurrentModificationException
	at java.util.HashMap$HashIterator.nextNode(Unknown Source)
	at java.util.HashMap$KeyIterator.next(Unknown Source)
	at TestThread.main(TestThread.java:48)