并发编程(二)-JUC
2021-07-28 本文已影响0人
Alan1914
1. 并发容器
1.1. BlockingQueue
在所有的并发容器中,BlockingQueue是最常见的一种。BlockingQueue是一个带阻塞功能的队
列,当入队列时,若队列已满,则阻塞调用者;当出队列时,若队列为空,则阻塞调用者。
在 concurrent BlockingQueue是一个interface

- ArrayBlockingQueue
ArrayBlockingQueue是一个用数组实现的环形队列,在构造方法中,会要求传入数组的容量。 - LinkedBlockingQueue
LinkedBlockingQueue是一种基于单向链表的阻塞队列。因为队头和队尾是2个指针分开操作的,
所以用了2把锁+2个条件,同时有1个AtomicInteger的原子变量记录count数。
在其构造方法中,也可以指定队列的总容量。如果不指定,默认为Integer.MAX_VALUE
。 - PriorityBlockingQueue
队列通常是先进先出的,而PriorityQueue是按照元素的优先级从小到大出队列的。正因为如此,
PriorityQueue中的2个元素之间需要可以比较大小,并实现Comparable接口。 - DelayQueue
DelayQueue即延迟队列,也就是一个按延迟时间从小到大出队的PriorityQueue。所谓延迟时间,
就是“未来将要执行的时间”减去“当前时间”。为此,放入DelayQueue中的元素,必须实现Delayed接
口 - SynchronousQueue
SynchronousQueue是一种特殊的BlockingQueue,它本身没有容量。先调put(...),线程会阻塞;
直到另外一个线程调用了take(),两个线程才同时解锁,反之亦然。对于多个线程而言,例如3个线程,
调用3次put(...),3个线程都会阻塞;直到另外的线程调用3次take(),6个线程才同时解锁,反之亦然。
1.2. BlockingDeque
1.3. CopyOnWrite
CopyOnWrite指在“写”的时候,不是直接“写”源数据,而是把数据拷贝一份进行修改,再通过悲观
锁或者乐观锁的方式写回。
那为什么不直接修改,而是要拷贝一份修改呢?
这是为了在“读”的时候不加锁。
- CopyOnWriteArrayList
- CopyOnWriteArraySet
1.4. ConcurrentLinkedQueue/Deque
AQS内部的阻塞队列实现原理:基于双向链表,通过对head/tail进行CAS操作,实现入队和出队。
ConcurrentLinkedQueue 的实现原理和AQS 内部的阻塞队列类似:同样是基于 CAS,同样是通过
head/tail指针记录队列头部和尾部,但还是有稍许差别。
1.5. ConcurrentHashMap
HashMap通常的实现方式是“数组+链表”,这种方式被称为“拉链法”。ConcurrentHashMap在这个
基本原理之上进行了各种优化。
1.6. ConcurrentSkipListMap/Set
ConcurrentHashMap 是一种 key 无序的 HashMap,ConcurrentSkipListMap则是 key 有序的,
实现了NavigableMap接口,此接口又继承了SortedMap接口。