队列是一种数据结构,它有两个基本操作:在队列尾部插入元素,和从队列头部移除一个元素,队列以一种先进先出的方式管理数据。
在java并发包中提供了基于内存的BlockingQueue的实现,常用的有ArrayBlockingQueue(数组形式存储)、LinkedBlockingQueue(以Node节点的链表形式存储)、PriorityBlockingQueue和DelayQueue
1、ArrayBlockingQueue:构造时需要指定容量,并可以选择是否需要公平性,如果是公平性设置为true,等待时间最长的线程会优先得到处理(其实就是通过ReentrantLock设置为true来达到公平性的)。它是基于数组的阻塞循环队列,此队列按照FIFO(先进先出)原则对元素进行排序
2、LinkedBlockingQueue:默认容量是Integer.MAX_VALUE,但是也可以选择指定其最大容量,它是基于链表的队列,此队列按照FIFO(先进先出)原则对元素进行排序
3、PriorityBlockingQueue:容量没有上限(即无界),带优先级的队列(对列中添加的元素要有比较能力),而不是先进先出的队列。元素按照优先级顺序被移除,它是基于堆数据结构的无界队列,无界意味着put时不会阻塞,但是会有内存资源被耗尽发生OutOfMemoryError的风险。队列为空时,取元素操作take就会阻塞。
4、DelayQueue:基于PriorityQueue来实现的,是一个存放Delayed 元素的无界阻塞队列。如果延迟都还没有期满,则队列没有头部,并且poll将返回null。当一个元素的getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。
1)offer:最常用方法,如果队里已满直接返回false,队列未满时直接插入返回true,带超时操作:boolean success = q.offer(x,100,TimeUnit.MILLISECONDS);
2)add:对offer方法的简单封装,如果队列已满,则直接抛出new IllegalStateException("Queue Full")
3)put:如果队列满则阻塞,会一直等待直到队列为空可以插入元素或者线程被中断抛出异常
1)poll:最常用方法,移除并返回队列头部元素,当队列为空返回null,带超时操作:Object head = q.poll(100, TimeUnit.MILLISECONDS);
2)remove:移除并返回队列头部元素,当队列为空时直接抛出NoSuchElementException异常
3)take:移除并返回队列头部元素,当队列为空时则会一直等待直到队列有元素可以取出或者线程被中断抛出异常
2)element:对peek方法的简单封装,返回队列头部元素,如果队列为空则抛出NoSuchElementException异常
注意:offer---->poll 相对应,put---->take相对应,一般情况下我们使用offer---->poll