博主原文地址:点击打开链接
阻塞队列与普通队列的区别在于,当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来
阻塞队列常用在多线程环境中,在生产者与消费者模式中应用十分广泛
阻塞队列的实现
package com.zhu.blockingqueue;
import java.util.LinkedList;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
public class MyBlockingQueue<E>{
//默认的队列容量
private static final int DEFAULT_CAPTITY=10;
private ReentrantLock lock=new ReentrantLock();
private Condition notFull=lock.newCondition();
private Condition notEmpty=lock.newCondition();
private E[] elements;
//队列的容量
private int capcity;
//队列目前的所包含的元素个数
private int size;
//队列头
private int head;
//队列尾
private int tail;
public MyBlockingQueue(){
this(DEFAULT_CAPTITY);
}
public MyBlockingQueue(int captity) {
if(captity<0){
throw new IndexOutOfBoundsException("index:"+captity);
}
this.capcity=captity;
head=tail=0;
elements=(E[]) new Object[captity];
}
public void put(E e) throws InterruptedException{
lock.lock();
try{
while(size==capcity){
notFull.await();
}
elements[tail]=e;
++size;
++tail;
tail=tail==capcity?0:tail;
}finally{
notEmpty.signalAll();
lock.unlock();
}
}
public E take() throws InterruptedException{
lock.lock();
E e;
try{
while(size==0){
notEmpty.await();
}
--size;
e=elements[head++];
head=head==capcity?0:head;
return e;
}finally{
notFull.signalAll();
lock.unlock();
}
}
}