【多线程与高并发】-Java如何实现一个阻塞队列呢?
Java要想实现一个阻塞队列,首先要明确阻塞队列的主要功能是什么:
- 队列的先进先出的功能;
- 队列的满的时候 放入的时候需要被阻塞;
- 队列为空的时候 取的时候需要被阻塞;
那么要想实现一个阻塞队列,我们需要两个锁,以及wait和notify来实现通信,并且通过getIndex和putIndex来实现。
// 阻塞队列
public final class ArrayQueue<T> {
// 队列数量
private int count = 0;
// 最终的数据存储
private Object[] items;
// 队列满时的阻塞锁
private Object full = new Object();
// 队列空时的阻塞锁
private Object empty = new Object();
//写入数据时的下标
private int putIndex;
// 获取数据时的下标
private int getIndex;
// 初始化
public ArrayQueue(int size) {
items = new Object[size];
}
// 获取大小
public int size() {
return count;
}
/**
* put方法 从队列尾写入数据
*/
public void put(T t) {
// 数据满的情况下
synchronized (full) {
while(count==items.length) {
try {
// 满了的情况下等待
full.wait();
}catch (InterruptedException e) {
// TODO: handle exception
break;
}
}
}
// 数据空的情况下
synchronized (empty) {
// 写入
items[putIndex++] = t;
count++;
// 查看是否到尾巴了
if(putIndex==items.length) {
// 超过数组长度后需要从头开始
putIndex=0;
}
// 有数据了唤醒
empty.notify();
}
}
// 从队列头获取数据
public T get() {
// 如果是空的情况
synchronized (empty) {
while(count==0) {
try {
empty.wait();
}catch (InterruptedException e) {
// TODO: handle exception
return null;
}
}
}
// 如果是满的情况下
synchronized (full) {
Object result = items[getIndex];
items[getIndex] = null;
getIndex++;
count--;
if(getIndex==items.length) {
getIndex=0;
}
// 唤醒线程
full.notify();
return (T)result;
}
}
}