队列
基本介绍
队列是一种数据结构,有点类似栈,不同的是,在队列中第一个插入的数据会被首先移
除。
特点:先进先出
效率:和栈一样,队列中插入数据和移除数据元素的时间复杂度都是O(1).
队列的使用
队列可分为两种,一种是阻塞队列,一种是非阻塞队列。
阻塞队列和非阻塞队列的区别在于:阻塞队列可以阻塞,非阻塞队列不能阻塞(废话)
非阻塞队列只能使用队列wait(),notify()进行队列消息传送。而阻塞队列当队列里面没
值时,会阻塞直到有值输入。输入也一样,当队列满的时候,会阻塞,直到队列不为
空。
常用阻塞队列
ArrayBlockingQueue
基于数组实现的一个阻塞队列,在创建ArrayBlockingQueue对象使,必须制定容器量
大小。并且可以指定公平性和非公平性,默认情况下为非公平性,即不保证等待时间最
长的队列最优先能访问队列。
LinkendBlockingQueue
基于链表实现的一个阻塞队列,在创建LinkedBlockingQueue对象时如果不指定容量大
小,则默认大小为Integer.max_vakue.
PriorityBlockingQueue
它会按照元素的优先级对元素进行排序,按照优先级顺序出队,每次出队的元素都是优
先级最高的元素。注意,此阻塞队列为无界队列,即容量没有上限。前面2个都是有界队
列。
DelayQueue
一种延时阻塞队列,DelayQueue中的元素只有当其指定的延迟时间到了,才能够从队列
中获取到该元素。DelayQueue也是一种无界队列,因此往队列中插入数据的操作永远不
会被阻塞,而只有获取数据的消费者才会被阻塞。
常用方法
以下五个方法,在阻塞队列和非阻塞队列中均可使用。对于非阻塞队列,一般情况下建
议使用offer(),poll(),和peek()三个方法,不建议使用add()和remove()方法。因为
使用offer,poll,和peek方法可以通过返回值判断操作成功与否,而使用add和remove方
法达不到这样的效果。注意,非阻塞队列中的方法都没进行同步措施!!!
方法名
方法描述
add(E e)
将元素e插入到队列末尾,如果成功返回true,如果失败或队列已满则抛出异常
remove()
移除队首元素,若移除成功,则返回true.如果失败或队列为空则返回false
offer(E e)
将元素e插入到队列末尾,如果成功返回true, 如果失败或队列已满则返回false
poll()
移除并获取队首元素,若成功则返回对首元素,否则返回null
peek()
获取队首元素,若成功则返回队首元素,否则返回null
阻塞队列中常用方法
阻塞队列包括了非阻塞队列中的大部分方法,上面列举的5个方法都在阻塞队列
中存在,但是要注意5个方法在阻塞队列中都进行了同步措施。
除此之外,阻塞队列提供了另外4种非常有用的方法:
方法名
方法描述
put(E e)
put方法用来向队尾存入元素,如果队列满,则等待
take()
tack方法用来从队首取元素,如果队列为空,则等待
offer(E e, long timeout, TimeUnit unit)
offer方法用来向队尾存入数据,如果队列满,则等待一定的时间,当时间期限到达时,如果还没有成功插入,则返回false;否则返回true.
poll( long timeout, TimeUnit unit)
poll方法用来从队首取元素,如果队列为空,则等待一定的时间,当时间期限到达时,如果还没有获取,则返回false,否则返回true.
阻塞队列之生产者消费者模型
需求分析
对于生产者消费者模型,如果库存为0,消费者需等待,如果库存已满,生产者需等待。
代码演示
public class test {
public static void main ( String[ ] args) {
test t = new test ( ) ;
Produce p = t. new Produce ( ) ;
Customer c = t. new Customer ( ) ;
p. start ( ) ; c. start ( ) ;
}