简述
14个线程安全容器( 都在 java.util.concurrent 包下)
- ConcurrentHashMap:并发版 HashMap
- CopyOnWriteArrayList:并发版 ArrayList
- CopyOnWriteArraySet:并发 Set
- ConcurrentLinkedQueue:并发队列 (基于链表)
- ConcurrentLinkedDeque:并发队列 (基于双向链表)
- ConcurrentSkipListMap:基于跳表的并发 Map
- ConcurrentSkipListSet:基于跳表的并发 Set
- ArrayBlockingQueue:阻塞队列 (基于数组)
- LinkedBlockingQueue:阻塞队列 (基于链表)
- LinkedBlockingDeque:阻塞队列 (基于双向链表)
- PriorityBlockingQueue:线程安全的优先队列
- SynchronousQueue:读写成对的队列
- LinkedTransferQueue:基于链表的数据交换队列
- DelayQueue:延时队列
总结
七大BlockingQueue的特点总结
| BlockQueue | bounded(有界) | add | offer | put | remove | poll | element | peek | take | transfer |
|---|---|---|---|---|---|---|---|---|---|---|
| ArrayBlockingQueue | Y | 1成功 return true ,2失败 抛出异常 | 1成功 return true ,2失败 return false | 如果队列已满,则会阻塞 | 移除头部元素,如果为null则会抛出异常 | 移除头部元素,如果为null则会抛出异常 | 移除头部元素并返回 | 获取头部元素,如果是null 抛异常 并不会删除元素 | 获取头部元素, 并不会删除元素 | null |
| PriorityBlockingQueue | N | 同offer | 成功返回true,绝不返回false 除非内存溢出 | 同offer | 同上 | 同上 | 同上 | 同上 | 同上 | null |
| LinkedBlockingQueue | Optional(可选) | 1成功 return true ,2失败 抛出异常 | 1成功 return true ,2失败 return false | 如果队列已满,则会阻塞 | 同上 | 同上 | 同上 | 同上 | 同上 | null |
| LinkedBlockingDeque | Optional(可选) | 同addLast | ||||||||
| SynchronousQueue | Y | 1成功 return true ,2失败 抛出异常 | 如果没有接受线程,返回false | 阻塞知道另外一个线程接受 | 移除头部元素,如果为null则会抛出异常 | 移除头部元素并返回 如果元素可用不为空否则为空 | 会永远抛出异常 | 直接 return null | 一直等待有线程transfer元素 | |
| DelayQueue | N | 同offer 如果是 false 抛异常 | 尾部插入元素,如果为ull 抛异常 | 同offer | 移除头部元素,如果为null则会抛出异常 | 如果没有元素或者元素过期都会返回null | 获取头部元素,如果是null 抛异常 并不会删除元素 | 获取头部元素,并不会删除元素 | 一直等待有线程放进元素,并且元素头部过期 | |
| LinkedTransferQueue | N | 尾部插入元素,永远返回true | 同add | 同add | 移除头部元素,如果为null则会抛出异常 | 移除头部元素并返回 | 获取头部元素,如果是null 抛异常 并不会删除元素 | 获取头部元素,并不会删除元素 | 一直等待,有线程放进元素 | 在队列尾部插入元素,如果没有被消费则一直等待 |
队列选用
如果你的程序强调对元素的增、删、改、查、遍历等操作就用LinkedList或者ArrayList;
如果是强调对象进入容器和对象从容器出来时的先后关系,那就用Stack、Queue、PriorityQueue
脑图
参考
常用的并发集合
14个Java并发容器,你用过几个?
BlockingQueue 笔记整理(包括 ArrayBlockingQueue、LinkedBlockingQueue、BlockingDeque、PriorityBlockingQueue等)