目录
【1】Java 7 中 ConcurrentHashMap 的实现原理
1.分段锁(Segment)
2. 数据结构
3. 操作流程
【2】Java 8 中 ConcurrentHashMap 的改进
1.红黑树的引入
2.CAS 操作
3.数据结构的变化
【3】ConcurrentHashMap 的常用方法及使用示例
1.put(K key, V value)
2.get(Object key)
3.computeIfAbsent(K key, FunctionmappingFunction)
【4】使用场景
【5】总结
ConcurrentHashMap是一个支持高并发的哈希表(类似HashMap)。与Hashtable不同,该类不依赖于synchronization去保证线程操作的安全。
【1】Java 7 中 ConcurrentHashMap 的实现原理
1.分段锁(Segment)
ConcurrentHashMap内部维护了一个Segment数组,每个Segment都是一个独立的锁,类似于一个小的HashTable。默认情况下,ConcurrentHashMap被分为 16 个Segment,这意味着理论上可以支持 16 个线程同时进行写入操作(前提是操作的是不同的Segment)。
2. 数据结构
每个Segment内部又维护了一个HashEntry数组,用于存储实际的键值对。HashEntry是一个链表结构,当发生哈希冲突时,新的元素会被添加到链表的头部。
3. 操作流程
get 操作:通过哈希算法计算出键对应的Segment索引,然后在对应的Segment中查找链表,找到对应的键值对。由于get操作并不需要对整个ConcurrentHashMap加锁,所以性能较高。
put 操作:同样先确定Segment索引,对对应的Segment加锁,然后在链表中查找或插入键值对。如果链表长度超过一定阈值,会进行扩容操作。
【2】Java 8 中 ConcurrentHashMap 的改进
1.红黑树的引入
在 Java 8 中,当链表长度超过 8 时,会将链表转换为红黑树。这是因为在哈希冲突较多的情况下,链表的查询时间复杂度为 O (n),而红黑树的查询时间复杂度为 O (log n),大大提高了查询效率。
2.CAS 操作
ConcurrentHashMap在一些操作中使用了 CAS 操作来避免锁竞争。例如在插入元素时,首先尝试使用 CAS 操作直接插入,如果失败再进行加锁操作。这样可以减少锁的使用,提高并发性能。
3.数据结构的变化
Java 8 中的ConcurrentHashMap不再使用Segment数组,而是直接使用一个Node数组来存储数据。Node节点有三种形态:普通节点(链表节点)、红黑树节点和 ForwardingNode(用于扩容时的标识节点)。
【3】ConcurrentHashMap 的常用方法及使用示例
1.put(K key, V value)
将指定的键值对插入到ConcurrentHashMap中。
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>(); map.put("apple", 10);
2.get(Object key)
根据指定的键获取对应的值。
Integer value = map.get("apple"); System.out.println(value); // 输出10
3.computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction)
如果指定的键不存在,则根据提供的映射函数计算出值并插入到ConcurrentHashMap中。
map.computeIfAbsent("banana", k -> 5);
4.forEach(BiConsumer<? super K,? super V> action)
遍历ConcurrentHashMap中的每一个键值对,并对其执行指定的操作。
map.forEach((k, v) -> System.out.println(k + ": " + v));
【4】使用场景
缓存系统:在缓存系统中,ConcurrentHashMap可以用来存储缓存数据,多线程可以同时读取和更新缓存,保证缓存的高效性和一致性。
计数器:用于统计一些并发的计数场景,如网站的访问量统计、任务的执行次数统计等,多个线程可以同时对计数器进行递增操作。
多线程任务的结果存储:在多线程计算任务中,每个线程计算的结果可以存储到ConcurrentHashMap中,最后汇总所有结果。
【5】总结
ConcurrentHashMap作为 Java 并发编程中的重要组件,不断演进和优化,为我们在多线程环境下提供了高效、安全的数据存储解决方案。通过深入理解它的实现原理、特性和使用方法,开发者可以更好地在实际项目中运用它,提升系统的并发性能和稳定性。随着 Java 技术的不断发展,相信ConcurrentHashMap还会带来更多的惊喜和优化。
感谢你花时间读到这里~ 如果你觉得这篇内容对你有帮助,不妨点个赞让更多人看到;如果有任何想法、疑问,或者想分享你的相关经历,欢迎在评论区留言交流,你的每一条互动对我来说都很珍贵~ 我们下次再见啦!😊😊