👏作者简介:大家好,我是爱吃芝士的土豆倪,24届校招生Java选手,很高兴认识大家📕系列专栏:Spring源码、JUC源码🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦🍂博主正在努力完成2023计划中:源码溯源,一探究竟📝联系方式:nhs19990716,加我进群,大家一起学习,一起进步,一起对抗互联网寒冬👀
文章目录 前置知识线程安全集合类概述ConcurrentHashMapConcurrentHashMap 原理JDK 7 HashMap 并发死链死链复现源码分析小结 JDK 8 ConcurrentHashMap重要方法构造器分析get 流程put 流程size 计算流程transfer JDK 7 ConcurrentHashMap构造器分析put 流程rehash 流程get 流程size 计算流程 BlockingQueueLinkedBlockingQueue 原理基本的入队出队加锁分析 CopyOnWriteArrayList迭代器弱一致性 相关推荐博客
前置知识
👉👉👉 如果面试也能这样说HashMap,那么就不会有那么多遗憾!-CSDN博客
线程安全集合类概述

线程安全集合类可以分为三大类:
遗留的线程安全集合如 Hashtable , Vector (出现时间比较早,而且所有方法都是用synchronized修饰,并发性能比较低,时至今日有更好的实现,更好的替代)使用 Collections 装饰的线程安全集合,如:(将原本不安全的集合变成安全的集合) Collections.synchronizedCollectionCollections.synchronizedListCollections.synchronizedMapCollections.synchronizedSetCollections.synchronizedNavigableMapCollections.synchronizedNavigableSetCollections.synchronizedSortedMapCollections.synchronizedSortedSet private static class SynchronizedMap
implements Map, Serializable { private static final long serialVersionUID = 1978198479659022715L; private final Map m; // Backing Map final Object mutex; // Object on which to synchronize SynchronizedMap(Map m) { this.m = Objects.requireNonNull(m); mutex = this; } public int size() { synchronized (mutex) {return m.size();} } public boolean isEmpty() { synchronized (mutex) {return m.isEmpty();} } public boolean containsKey(Object key) { synchronized (mutex) {return m.containsKey(key);} } public boolean containsValue(Object value) { synchronized (mutex) {return m.containsValue(value);} } public V get(Object key) { synchronized (mutex) {return m.get(key);} } public V put(K key, V value) { synchronized (mutex) {return m.put(key, value);} } public V remove(Object key) { synchronized (mutex) {return m.remove(key);} } public void putAll(Map extends K, ? extends V> map) { synchronized (mutex) {m.putAll(map);} } public void clear() { synchronized (mutex) {m.clear();} } 传入的就是线程不安全的map,将其变成线程安全的
本质上就是多加了一个synchronized 锁住了对象
java.util.concurrent.*重点介绍 java.util.concurrent.* 下的线程安全集合类,可以发现它们有规律,里面包含三类关键词:
Blocking、CopyOnWrite、Concurrent
Blocking 大部分实现基于锁,并提供用来阻塞的方法(很多方法在不满足条件的时候需要等待)
CopyOnWrite 之类容器修改开销相对较重(适用于读多写少)
Concurrent 类型的容器
内部很多操作使用 cas 优化,一般可以提供较高吞吐量
弱一致性
遍历时弱一致性,例如,当利用迭代器遍历时,如果容器发生修改,迭代器仍然可以继续进行遍历,这时内容是旧的求大小弱一致性,size 操作未必是 100% 准确读取弱一致性 遍历时如果发生了修改,对于非安全容器来讲,使用 fail-fast 机制也就是让遍历立刻失败,抛出ConcurrentModificationException,不再继续遍历
一致性 和 性能 两者不可兼得
ConcurrentHashMap生成测试数据
static final String ALPHA ="abcedfghijklmnopqrstuvwxyz"; public static void main(String[] args) { int length = ALPHA.length(); int count = 200; List list = new ArrayList<>(length * count); for (int i = 0; i < length; i++) { char ch = ALPHA.charAt(i); for (int j = 0; j < count; j++) { list.add(String.valueOf(ch)); } } Collections.shuffle(list); for (int i = 0; i < 26; i++) { try (PrintWriter out = new PrintWriter( new OutputStreamWriter( new FileOutputStream("tmp/"+ (i+1) +".txt")))) { String collect = list.subList(i * count, (i + 1) * count).stream() .collect(Collectors.joining("\n")); out.print(collect); } catch (IOException e) { } } } 模版代码,模版代码中封装了多线程读取文件的代码
private static void demo(Supplier