[TOC]
> 本文视频讲解:https://www.bilibili.com/video/BV1Lb4y1d7L7
## 什么是阻塞队列
阻塞队列是一个在队列基础上又支持了两个附加操作的队列,常应用于解耦。
两个附加操作:
1. 支持阻塞的插入方法:队列满时,队列会阻塞插入元素的线程,直到队列不满。
2. 支持阻塞的移除方法:队列空时,获取元素的线程会等待队列变为非空。
阻塞队列是哪里用到的?阻塞队列是线程池的自定义参数之一。<br>
和JDK集合包中的Queue接兼容,同时在其基础上增加了阻塞功能。
定义的接口,而pu(.)是阻塞的。
### 说一下JUC中BlockingQueue接口主要的方法和特点?
条件:
notEmpty:非空状态,take()线程可以在队列中取数据;
notFull:未满装填,put()线程可以在队列中放数据;
#### 说一说BlockingQueue常 用的实现类?
**说一下ArrayBlockingQueue的设计?**
> 一个对象数组 + 一把锁 + 两个条件
是一个用数组实现的有界阻塞队列,此队列按照先进先出(FIFO)的原则对元素进行排序。支持公平锁和非公平锁。
1. ArrayBlockingQueue是一个用数组实现的环形队列,在构造方法中,会要求传入数组的容量。
2. 入队与出队都用同一把锁只有入队高并发或出队高并发的情况下,操作数组不需要扩容,性能很高。
> 注:每一个线程在获取锁的时候可能都会排队等待,如果在等待时间上,先获取锁的线程的请求一定先被满足,那么这个锁就是公平的。反之,这个锁就是不公平的。公平的获取锁,也就是当前等待时间最长的线程先获取锁
##### 说一下LinkedBlockingQueue的设计?
```
public class LinkedBlockingQueue<E> extends AbstractQueue<E>
implements BlockingQueue<E>, java.io.Serializable {
/** The capacity bound, or Integer.MAX_VALUE if none */
private final int capacity;
/** Current number of elements */
private final AtomicInteger count = new AtomicInteger();
/**
* Head of linked list.
* Invariant: head.item == null
*/
transient Node<E> head;
/**
* Tail of linked list.
* Invariant: last.next == null
*/
private transient Node<E> last;
/** Lock held by take, poll, etc */
private final ReentrantLock takeLock = new ReentrantLock();
/** Wait queue for waiting takes */
private final Condition notEmpty = takeLock.newCondition();
/** Lock held by put, offer, etc */
private final ReentrantLock putLock = new ReentrantLock();
/** Wait queue for waiting puts */
private final Condition notFull = putLock.newCondition();
……
}
```
- 两把锁:put()操作和take()操作,分别对应一把锁,本质上操作的是Node对象;
- 相互通知:put()线程未满,通知其他put()线程,会通知take()线程;
##### 说-下PriorityBlockingQueue的设计?
#### SynchronousQueue
![](https://img.kancloud.cn/1f/90/1f9086d453fd2c3a2cbee8a865e20119_1136x362.png)
SynchronousQueue: 一个不存储元素的阻塞队列,每一个put()操作必须等待take()操作,否则不能添加元素。支持公平锁和非公平锁。SynchronousQueue的一个使用场景是在线程池里。Executors.newCachedThreadPool()就使用了SynchronousQueue,这个线程池根据需要(新任务到来时)创建新的线程,如果有空闲线程则会重复使用,线程空闲了60秒后会被回收。
### 应用场景
## 总结
![](https://img.kancloud.cn/03/f0/03f0767de4929e3c4a2bea3c5041af75_909x465.png)
- 前言
- 第一部分 计算机网络与操作系统
- 大量的 TIME_WAIT 状态 TCP 连接,对业务有什么影响?怎么处理?
- 性能占用
- 第二部分 Java基础
- 2-1 JVM
- JVM整体结构
- 方法区
- JVM的生命周期
- 堆对象结构
- 垃圾回收
- 调优案例
- 类加载机制
- 执行引擎
- 类文件结构
- 2-2 多线程
- 线程状态
- 锁与阻塞
- 悲观锁与乐观锁
- 阻塞队列
- ConcurrentHashMap
- 线程池
- 线程框架
- 彻底搞懂AQS
- 2-3 Spring框架基础
- Spring注解
- Spring IoC 和 AOP 的理解
- Spring工作原理
- 2-4 集合框架
- 死磕HashMap
- 第三部分 高级编程
- Socket与NIO
- 缓冲区
- Bybuffer
- BIO、NIO、AIO
- Netty的工作原理
- Netty高性能原因
- Rabbitmq
- mq消息可靠性是怎么保障的?
- 认证授权
- 第四部分 数据存储
- 第1章 mysql篇
- MySQL主从一致性
- Mysql的数据组织方式
- Mysql性能优化
- 数据库中的乐观锁与悲观锁
- 深度分页
- 从一条SQL语句看Mysql的工作流程
- 第2章 Redis
- Redis缓存
- redis key过期策略
- 数据持久化
- 基于Redis分布式锁的实现
- Redis高可用
- 第3章 Elasticsearch
- 全文查询为什么快
- battle with mysql
- 第五部分 数据结构与算法
- 常见算法题
- 基于数组实现的一个队列
- 第六部分 真实面试案例
- 初级开发面试材料
- 答案部分
- 现场编码
- 第七部分 面试官角度
- 第八部分 计算机基础
- 第九部分 微服务
- OpenFeign工作原理