关于java:ConcurrentHashMap的示例

examples of ConcurrentHashMap

我正在阅读"Java理论与实践:构建一个更好的HashMap"这篇文章,这篇文章对CONCURESHASMAP的实现给出了一个很好的概述。

我在StackOverflow上也发现了一些关于它的讨论。

尽管我的脑海里有这样一个问题:使用ConcurrentHashMap的"场景/应用程序/地点是什么"。

谢谢你


在相同的情况下,您将使用一个ConcurrentHashMap,您将使用一个HashMap,除非您计划使用映射在多个线程上。


对于大型映射或大量读写操作,建议使用ConcurrentHashMap,因为:

  • 从地图上看时,它没有锁定。因此,如果5个线程正在从中读取,那么它们都可以同时从映射中读取。
  • 在写入时,只有相关记录(键)被锁定。因此,如果5个线程正在写入不同键的值,那么所有这些操作都可以同时进行。但是,如果两个线程正在写入同一个密钥,那么这些操作是线程安全的。发生这种情况是因为在对象(map)级别没有锁定,而是在更细的粒度上——在hashmap bucket级别。

请考虑以下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class ConcurrentHashMapExample {

    public static void main(String[] args) {

        //ConcurrentHashMap
        Map<String,String> myMap = new ConcurrentHashMap<String,String>();
        myMap.put("1","1");
        myMap.put("2","1");
        myMap.put("3","1");
        myMap.put("4","1");
        myMap.put("5","1");
        myMap.put("6","1");
        System.out.println("ConcurrentHashMap before iterator:"+myMap);
        Iterator<String> itr1 = myMap.keySet().iterator();

        while(itr1.hasNext()){
            String key = itr1.next();
            if(key.equals("3")) myMap.put(key+"new","new3");
        }
        System.out.println("ConcurrentHashMap after iterator:"+myMap);

        //HashMap
        myMap = new HashMap<String,String>();
        myMap.put("1","1");
        myMap.put("2","1");
        myMap.put("3","1");
        myMap.put("4","1");
        myMap.put("5","1");
        myMap.put("6","1");
        System.out.println("HashMap before iterator:"+myMap);
        Iterator<String> itr2 = myMap.keySet().iterator();

        while(itr2.hasNext()){
            String key = itr2.next();
            if(key.equals("3")) myMap.put(key+"new","new3");
        }
        System.out.println("HashMap after iterator:"+myMap);
    }
}

输出将是:

1
2
3
4
5
6
7
ConcurrentHashMap before iterator: {1=1, 5=1, 6=1, 3=1, 4=1, 2=1}
ConcurrentHashMap after iterator: {1=1, 3new=new3, 5=1, 6=1, 3=1, 4=1, 2=1}
HashMap before iterator: {3=1, 2=1, 1=1, 6=1, 5=1, 4=1}
Exception in thread"main" java.util.ConcurrentModificationException
    at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
    at java.util.HashMap$KeyIterator.next(HashMap.java:828)
    at com.test.ConcurrentHashMapExample.main(ConcurrentHashMapExample.java:44)

如您所见,对于HashMap来说,由于您试图更改当前正在迭代的映射,将抛出ConcurrentModificationException!(具体来说,例外情况将在声明中提出:String key = itr1.next();)


例如,我使用它在多线程服务器中快速查找从用户ID到用户对象的信息。

我有一个网络线程、一个用于定期任务的计时器线程和一个用于处理控制台输入的线程。多个线程访问用户的哈希图,因此它需要是线程安全的。