自学内容网 自学内容网

ConcurrentHashMap的使用

ConcurrentHashMap概述

ConcurrentHashMap是Java 并发包(java.util.concurrent)中提供的一个线程安全且高效的哈希表实现,用于在并发环境中存储键值对,它允许在多个线程之间安全地共享和修改数据,使得开发者无需显式同步代码就能在并发环境下安全使用。与同样是线程安全的哈希表HashTable相比,ConcurrentHashMap具有更高的并发效率。

ConcurrentHashMap的实现

Java7中的实现

        在 Java7中,ConcurrentHashMap使用了分段锁(Segment)的技术来实现并发访问的安全性。这个设计思想是将整个ConcurrentHashMap分成若干个Segment(默认为16),每个Segment相当于一个小型的哈希表,拥有自己的锁。这样,在进行put操作时,只需要锁定当前操作Segment而不是整个 Map,多个线程就能同时操作不同的段,在并发环境下将实现更高的吞吐量,而在单线程环境下只损失非常小的性能。Segment使用可重入锁ReentrantLock实现。

Java8中的实现

        在 Java8中对ConcurrentHashMap进行了重大改进,具体包括进一步细化了锁粒度,摒弃了原有的分段锁的设计,转而采用了CAS+synchronized的同步方式,锁住的不再是一个段,而是某个节点,即只有HashCode相同的元素才可能阻塞,进一步提高了并发性能。与HashMap一样,Java8中ConcurrentHashMap底层数据结构也由数组+链表改为了数组+链表+红黑树。至于引入红黑树的理由我想和HashMap是一样的。之前写了一篇关于HashMap文章有详细介绍,请参考:【Java集合】HashMap

示例代码

ConcurrentHashMap使用增强for循环或forEach遍历集合时可以删除元素,而不像HashMap、ArrayList等其它集合需要使用迭代器。遍历集合时删除元素问题

public static void main(String[] args) {
        Map<String, Integer> conMap = new ConcurrentHashMap<>();
        for (int i = 0; i < 10; i++) {
            conMap.put("key"+i, i);
        }

        for (Map.Entry<String, Integer> entry : conMap.entrySet()) {
            int v = entry.getValue();
            if (v < 5) {
                conMap.remove(entry.getKey());
            }
        }
        System.out.println(conMap);
    }
//输出
{key5=5, key6=6, key9=9, key7=7, key8=8}

一个线程对ConcurrentHashMap执行插入,另一个线程可以实时读取,ConcurrentHashMap保证了线程之间的安全性和可见性。

public static void main(String[] args) {
    Map<String, Integer> conMap = new ConcurrentHashMap<>();
    Thread thread1 = new Thread(() -> {
        for (int i = 0; i < 10; i++) {
            conMap.put("key"+i, i);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

    Thread thread2 = new Thread(() -> {
        while (true){
            System.out.println("size="+conMap.size());
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });

    thread1.start();
    thread2.start();
}
//输出
size=0
size=1
size=2
size=3
size=4
size=5
size=6
size=7
size=8
size=9
size=10
size=10
size=10
...

总结

总之ConcurrentHashMap是一个高性能的Java并发容器,是多线程下常用的map容器,其使用方法基本可以参考HashMap。


原文地址:https://blog.csdn.net/qq_38875964/article/details/142458627

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!