首先队列是一种前进后出的操作结构,也就是说它只允许从队列前端进入,从队列后端退出。这个前端和后端看个人如何理解,也就是通常所说的入队和出队,队头和队尾。
阻塞队列和一般队列的不同就在于阻塞队列是可以阻塞的,这里所说的并不是说队列中间或者队头队尾被拦截了,而是一种操作队列的线程的一种状态。在阻塞队列中,线程阻塞有两种情况。
- 消费者阻塞:也就是说,在队列为空的时候,没有任何数据的时候,队列消费者端就会被自动阻塞,一直到有任务进入到队列之后,消费者的线程就会被自动的唤起来消费任务。
- 生产者阻塞: 在队列已经满了,或者是没有可用空间的时候,生产者端的线程都会被阻塞,直到队列中的线程被消耗,有位置进入的时候,线程被自动唤醒,并且生产数据。
二者分别对应的出队,入队操作,当队列为空的时候,出队阻塞,当队列满的时候,入队阻塞。
阻塞队列的主要操作
阻塞队列的主要操作有插入操作和移除操作。插入操作有add()、offer()、put(),移除操作有 remove()、poll()、take() 具体如下。
1、插入操作
public abstract boolean add(E paramE) ;将指定的元素插入到队列中,在成功的时候返回true,如果当前没有可用的空间,就会抛出IllegalStateException。如果该元素是null,就会抛出NullPointException的异常。
public boolean add(E e) {
// 添加元素成功,返回 true
if (offer(e))
return true;
// 添加元素失败,抛出异常
else
throw new IllegalStateException("Queue full");
}
public abstract boolean offer(E paramE);将指定的元素插入队列中,在成功的时候返回true,如果没有可以用的空间,则返回false。源码如下
public boolean offer(E e) {
// 检查元素是否为空
checkNotNull(e);
final ReentrantLock lock = this.lock;
// 获取锁操作
lock.lock();
try {
// 如果队列满了,则返回false
if (count == items.length)
return false;
else {
// 如果队列为空,则将元素加入到队列中
enqueue(e);
return true;
}
} finally {
// 操作成功释放锁
lock.unlock();
}
}
offer(E o,long timeout,TimeUnit unit);将指定的元素插入到队列中,可以设置等待时间,如果在设定的等待时间内不能向队列中加入这个元素,就会返回false
public boolean offer(E e, long tim