📜  Java并发-ConcurrentMap接口

📅  最后修改于: 2020-11-15 04:00:42             🧑  作者: Mango


java.util.concurrent.ConcurrentMap接口是Map接口的子接口,支持对基础map变量的原子操作。它具有get和set方法,它们的工作方式类似于对易失性变量的读写。也就是说,一个集合与该变量的任何后续get都具有事前发生的关系。该接口确保线程安全性和原子性保证。

ConcurrentMap方法

Sr.No. Method & Description
1

default V compute(K key, BiFunction remappingFunction)

Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).

2

default V computeIfAbsent(K key, Function mappingFunction)

If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.

3

default V computeIfPresent(K key, BiFunction remappingFunction)

If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.

4

default void forEach(BiConsumer action)

Performs the given action for each entry in this map until all entries have been processed or the action throws an exception.

5

default V getOrDefault(Object key, V defaultValue)

Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.

6

default V merge(K key, V value, BiFunction remappingFunction)

If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value.

7

V putIfAbsent(K key, V value)

If the specified key is not already associated with a value, associate it with the given value.

8

booleanremove(Object key, Object value)

Removes the entry for a key only if currently mapped to a given value.

9

V replace(K key, V value)

Replaces the entry for a key only if currently mapped to some value.

10

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

Replaces the entry for a key only if currently mapped to a given value.

11

default void replaceAll(BiFunction function)

Replaces each entry’s value with the result of invoking the given function on that entry until all entries have been processed or the function throws an exception.

下面的TestThread程序显示了ConcurrentMap vs 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 map = new ConcurrentHashMap();

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

      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)