ConcurrentHashMap 的示例

发布于 2024-09-30 11:27:20 字数 418 浏览 1 评论 0原文

我正在阅读文章“Java理论与实践:构建更好的HashMap” 很好地概述了 ConcurrentHashMap 的实现。

我还在 Stackoverflow 此处找到了一些关于它的讨论。

我的疑问是“使用 ConcurrentHashMap 的场景/应用程序/地点是什么”。

谢谢

I was reading the article "Java theory and practice: Building a better HashMap" that gives an excellent overview about the implementation of ConcurrentHashMap.

I also found some discussions over it on Stackoverflow here.

I question though I had in my mind is "what are the scenarios/applications/places" where ConcurrentHashMap is used.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

深海夜未眠 2024-10-07 11:27:20

您可以在使用 HashMap 的相同实例中使用 ConcurrentHashMap,只不过您计划在多个线程上使用该映射。

You would use a ConcurrentHashMap in the same instances you would use a HashMap, except that you plan on more than one thread using the map.

窝囊感情。 2024-10-07 11:27:20

例如,我使用它来快速查找多线程服务器中的用户 ID 和用户对象。

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

I use it for quick lookup from user ids to user objects in a multi-threaded server for instance.

I have a network-thread, a timer thread for periodical tasks and a thread for handling console input. Multiple threads access the hash map of users, thus it needs to be thread safe.

水染的天色ゝ 2024-10-07 11:27:20

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

  • 从 Map 读取时,它没有锁定。因此,如果 5 个线程正在从中读取,则所有线程都可以同时从 Map 中读取。
  • 写入时,仅锁定相关记录(密钥)。因此,如果 5 个线程正在写入不同键的值,则所有这些操作都可以同时发生。但是,如果两个线程正在写入同一个键,则这些操作是线程安全的。发生这种情况是因为在对象(映射)级别没有锁定,而是在更细的粒度(哈希映射存储桶级别)上锁定。

考虑以下示例:

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 ,将抛出 ConcurrentModificationException 因为您试图更改当前迭代的映射! (具体来说,异常将在语句上抛出:String key = itr1.next();

Using ConcurrentHashMap is recommended for large Maps or large number of read-write operations due to:

  • When reading from the map, it's not locked. Thus, if 5 threads are reading from it, all of them can simultaneously read from map.
  • On writing, only the relevant record (key) is locked. Thus, if 5 threads are writing values of different keys, all those operations can happen simultaneously. However, if 2 threads are writing to same key, those operations are thread-safe. That happens because there is no locking at the object (map) level but at a much finer granularity - at a hashmap bucket level.

Consider the following example:

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

The output will be:

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)

As you can see, for the HashMap a ConcurrentModificationException will be thrown because you trying to change a map that you currently iterating on! (specifically, the exception will be thrown on the statement : String key = itr1.next();)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文