并发容器与队列

笔记/Java/Java基础/Java并发/并发容器与队列

上一篇:ThreadLocal · 面试:并发编程面试 123 道

同步容器 vs 并发容器#

类型例子特点
同步容器Vector、Hashtable、Collections.synchronizedXxx全表/全方法锁,竞争大
并发容器ConcurrentHashMap、CopyOnWriteArrayList锁分离/CAS/写时复制,吞吐高

Hashtable.size() 需同步:否则与 put 并发时可能读到不一致计数。

ConcurrentHashMap#

JDK 7:Segment 分段锁。
JDK 8+:Node 数组 + 链表/红黑树;CAS + synchronized 锁桶头,粒度更细;读大多无锁。

与 Hashtable:Hashtable 锁整张表;CHM 锁桶/ CAS,并发度高。

Collections.synchronizedMap 包装 HashMap,仍是全 map 锁。

CopyOnWriteArrayList#

写时复制:写操作复制新数组,读无锁遍历旧数组。

  • 适合 读多写少(配置、监听器列表)
  • 缺点:写开销大、内存占用、读可能短暂不一致(最终一致)

阻塞队列 BlockingQueue#

用于生产者-消费者、线程池任务队列:

队列特点
ArrayBlockingQueue有界数组 FIFO
LinkedBlockingQueue可选有界,链表 FIFO
SynchronousQueue不存元素,直接交接
DelayQueue延迟到期才能取
PriorityBlockingQueue优先级无界

常用方法:put/take(阻塞)、offer/poll(非阻塞或超时)。

非阻塞并发队列#

ConcurrentLinkedQueue:CAS 无锁链表,高并发入队出队。

线程安全 HashMap 选型#

  • 单线程:HashMap
  • 并发读多写少:ConcurrentHashMap
  • 需全表锁简单方案:Collections.synchronizedMap(性能较差)
  • 不要用 HashMap 多线程写(可能死循环/JDK7、数据丢失/JDK8+)

一句话总结#

多线程共享 Map 用 ConcurrentHashMap;读多写少列表用 CopyOnWrite;任务排队用 BlockingQueue 配合线程池。

文章目录

文章目录