阻塞队列是Concurrent包下的类,常用的包括ArrayBlockingQueue和LinkedBlockingQueue,阻塞队列中put()和take()两个方法的实现从源码中华可以看出是用消费者-生产者模式实现的,下面就是自己实现的简单的ArrayBlockingQueue
废话诗少说,直接上代码:
class MyBlockingQueue<E> {
// 默认的队列容量
private static final int DEFAULT_CAPACITY = 128;
// 存储队列元素的数组
private E[] queue;
// 队列初始容量
private int capacity;
// 队列中元素个数
private int size;
// 队头索引
private int head;
// 队尾索引
private int tail;
// 显示锁
private Lock lock = new ReentrantLock();
private Condition notFull = lock.newCondition();
private Condition notEmpty = lock.newCondition();
public MyBlockingQueue() {
this(DEFAULT_CAPACITY);
}
public MyBlockingQueue(int capacity) {
this.capacity = capacity;
queue = (E[]) new Object[capacity];
}
// 添加一个元素到队尾,如果队列已满,该方法将阻塞
public void put(E element) throws InterruptedException {
lock.lock();
try {
while (size >= capacity) {
notFull.await();
}
queue[tail] = element;
if (++tail == capacity) {
tail = 0;
}
++size;
notEmpty.signal();
} finally {
lock.unlock();
}
}
//从队头移除一个元素,并返回该元素,如果队列为空,将阻塞直到有元素为止
public E take() throws InterruptedException {
lock.lock();
try {
while (size == 0) {
notEmpty.await();
}
E value = queue[head];
queue[head] = null;
if (++head == capacity) {
head = 0;
}
--size;
notFull.signal();
return value;
} finally {
lock.unlock();
}
}
}
实现的功能比较简单,仅仅实现了put()和take()两个方法,真正的阻塞队列当然要复杂的对,但是这两个方法应该是阻塞队列区别于其他队列的两个最核心的方法。。。。。。。