阻塞队列与普通队列的区别在于:阻塞队列为空时,从队列中获取元素的操作将会被阻塞,当队列为满时,往队列里添加元素的操作会被阻塞。
试图从空的阻塞队列中获取元素的线程将会被阻塞,直到其他的线程往空的队列插入新的元素。同样,试图往已满的阻塞队列中添加新元素的线程同样也会被阻塞,直到其他的线程使队列重新变得空闲起来
2、阻塞队列的简单实现
<pre>/**
- 基于链表实现的一个阻塞队列
- @author jade
*
*/
public class BlockingQueue {
private int capacity ; // 阻塞队列容量
private List queue = new LinkedList(); // 基于链表实现的一个阻塞队列
public BlockingQueue() {
this(Integer.MAX_VALUE);
}
public BlockingQueue(int capacity) {
this.capacity = capacity;
}
/**
* 入队列
*
* @param item
* @throws InterruptedException
*/
public synchronized void enqueue(Object item) throws InterruptedException {
while (this.queue.size() == this.capacity) {
wait();
}
if (this.queue.size() == 0) {
notifyAll();
}
this.queue.add(item);
}
/**
* 出队列
*
* @return
* @throws InterruptedException
*/
public synchronized Object dequeue() throws InterruptedException {
while (this.queue.size() == 0) {
wait();
}
if (this.queue.size() == this.capacity) {
notifyAll();
}
return this.queue.remove(0);
}
re>
注意:
1)在和方法内部,只有队列的大小等于上限()或者下限(0)时,才调用方法,小于时不调用。
如果队列的大小既不等于上限java链表和队列,也不等于下限,任何线程调用或者方法时,都不会阻塞,就不需要唤醒,都能够正常的往队列中添加或者移除元素。
2)和方法都加了 ,在进入的时候获取锁,退出的时候释放锁。而如果没有,直接使用wait/时java链表和队列 阻塞队列 - java基于链表的简单实现,无法确认哪个锁。
3、
在java.util.包下提供了若干个阻塞队列,其中基于链表实现的一个阻塞队列,在创建对象时如果不指定容量大小,则默认大小为.。
首先看一下类中的几个成员变量:
<pre> private static final long serialVersionUID = -6903933977591709194L;
private final int capacity;
private final AtomicInteger count = new AtomicInteger();
transient Node head;
private transient Node last;
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = this.takeLock.newCondition();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = this.putLock.newCondition();</pre>
可以看出,中用来存储元素的实际上是一个链表,head和last分别表示链表的头节点和下一节点, 表示队列的容量。
, 是可重入锁,和是等待条件。
下面看一下的构造器,构造器有三个重载版本:
<p><pre> public LinkedBlockingQueue()
{
this(Integer.MAX_VALUE);
}
public LinkedBlockingQueue(int paramInt)
{
if (paramInt