ConcurrentHashMap 的例子

6
我正在阅读文章“Java理论与实践:构建更好的HashMap”,它对ConcurrentHashMap的实现进行了优秀的概述。
我在Stackoverflow上也发现了一些讨论这里
我心中的疑问是:“ConcurrentHashMap在哪些场景/应用/地方被使用?”
谢谢。
3个回答

6

如果你计划让多个线程使用地图,那么在与使用HashMap相同的情况下,你将使用ConcurrentHashMap


2

对于大型Map或大量读写操作,建议使用ConcurrentHashMap,原因如下:

  • 在从Map中读取数据时,不会锁定整个Map。因此,如果有5个线程从Map中读取数据,则它们都可以同时读取Map中的数据。
  • 在写入数据时,只锁定相关记录(key)。因此,如果有5个线程在写入不同key的值,则所有这些操作都可以同时进行。但是,如果2个线程正在写入同一个key,则这些操作是线程安全的。这是因为对象(Map)级别上没有锁定,而是在更细粒度的哈希桶级别上进行锁定。

考虑以下示例:

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

输出结果将是:
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时尝试更改Map中的值,就会出现ConcurrentModificationException异常!(具体来说,在执行语句:String key = itr1.next(); 时会抛出异常)


2

我将其用于多线程服务器中从用户ID到用户对象的快速查找。

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接