【java并发编程的艺术读书笔记】ConcurrentHashMap是如何保证线程安全的

ConcurrentHashMap

HashMap的线程安全问题

并发环境下HashMap可能会导致程序死循环,原因是put操作可能会使得HashMap中的链表结构成环,导致无法找到next节点,无限循环

HashTable为什么效率低

HashMap是使用synchronized来保证县城安全的,如果并发量非常高,那么会触发synchronized锁升级机制,成为重量级锁,性能严重降低

ConcurrentHashMap是如何保证线程安全的

HashMap效率的原因是使用了同一把锁,如果有多把锁那么效率就会提高了,ConcurrentHashMap就是这么做的分段锁,ConcurrentHashMap是将数据分成一段一段的,默认情况下,ConcurrentHashMap 会创建 16 个段。然后每一段数据一把锁,当进行插入、查找或删除操作时,ConcurrentHashMap 首先根据键的哈希值计算出段的索引,然后在对应的段中进行操作。这意味着不同的键可以并发地在不同的段中进行操作,从而减少了线程之间的争用。其数据结构是由一个Segment数组和一个HashEntry数组组成的,Segment是一种KV结构的可重入锁

【java并发编程的艺术读书笔记】ConcurrentHashMap是如何保证线程安全的_第1张图片

ConcurrentHashMap的特点

  1. 分段锁设计:ConcurrentHashMap 使用了分段锁的机制,将哈希表分成多个段(Segment),每个段都拥有自己的锁。这样不同的段可以并发地进行操作,从而提高了并发性能。默认情况下,ConcurrentHashMap 会创建 16 个段。

  2. 并发安全:由于使用了分段锁,不同段的操作可以并行执行,这使得 ConcurrentHashMap 在多线程环境下能够提供较高的并发性能,同时避免了传统 HashMap 的并发问题。

  3. 支持高并发读写:ConcurrentHashMap 的读操作不需要锁,可以在不阻塞其他读操作的情况下并发进行。只有写操作会锁定相应的段,以保障写操作的原子性。

  4. 线程安全迭代器:ConcurrentHashMap 提供了一种安全的迭代器,可以在迭代时进行并发的读操作,而不会导致 ConcurrentModificationException 异常。

  5. 高度可调整性:可以通过调整初始化大小、负载因子和并发级别等参数来优化 ConcurrentHashMap 的性能。

使用案例

import java.util.concurrent.ConcurrentHashMap;

public class ConcurrentHashMapExample {
    public static void main(String[] args) {
        ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();

        map.put("one", 1);
        map.put("two", 2);
        map.put("three", 3);

        // 并发安全地进行读操作
        int result = map.getOrDefault("two", 0);
        System.out.println("Result: " + result);

        // 并发安全地进行写操作
        map.putIfAbsent("four", 4);

        // 迭代器也是并发安全的
        map.forEach((key, value) -> System.out.println(key + ": " + value));
    }
}

你可能感兴趣的:(读书笔记,java,开发语言,HashMap,并发编程,Concurrent,分段锁)