前言
Java的线程池中,在核心线程数已满的情况下,任务会存储在阻塞队列中,那么什么是阻塞队列呢?
阻塞队列首先是个队列,在队列的基础上,支持另外两个附加操作:
- 在队列为空时,获取元素的线程会等待队列变为非空
- 在队列满时,添加元素的线程会等待队列可用
那么阻塞队列是如何实现阻塞的?
自己实现一个阻塞队列
Synchronized、wait、notifyAll实现的阻塞队列
public class BlockingQueue {
// 放置元素索引
private int inputIndex;
// 取出元素索引
private int takeIndex;
// 元素数组
private String[] elements;
// 数组中元素数量
private int count;
public BlockingQueue(int capacity) {
elements = new String[capacity];
}
public Object take() throws InterruptedException {
synchronized(this) {
// 这里使用while的原因是线程被唤醒之后需要再判断一次数组是否已经有元素
while (count == 0) {
// 数组没有元素了,等待
this.wait();
}
Object e = dequeue();
this.notify();
System.out.println("take method: " + Arrays.toString(elements));
return e;
}
}
public void put(String str) throws InterruptedException {
synchronized (this) {
// 这里使用while的原因是线程被唤醒之后需要再判断一次数组元素是否有空闲位置
while (count == elements.length) {
// 数组元素满了,等待
this.wait();
}
enqueue(str);
System.out.println("put method: " + Arrays.toString(elements));
this.notify();
}
}
/**
* 入队方法
* @param e 元素
*/
private void enqueue(String e) {
elements[inputIndex] = e;
// 如果数组已满,input返回开头
if (++inputIndex == elements.length) {
inputIndex = 0;
}
count +