Queue: 基本上,一个队列就是一个先入先出(FIFO)的数据结构java
Queue接口与List、Set同一级别,都是继承了Collection接口。LinkedList实现了Deque接 口。数组
Queue的实现安全
一、没有实现的阻塞接口的LinkedList: 实现了java.util.Queue接口和java.util.AbstractQueue接口
内置的不阻塞队列: PriorityQueue 和 ConcurrentLinkedQueue
PriorityQueue 和 ConcurrentLinkedQueue 类在 Collection Framework 中加入两个具体集合实现。
PriorityQueue 类实质上维护了一个有序列表。加入到 Queue 中的元素根据它们的自然排序(经过其 java.util.Comparable 实现)或者根据传递给构造函数的 java.util.Comparator 实现来定位。
ConcurrentLinkedQueue 是基于连接节点的、线程安全的队列。并发访问不须要同步。由于它在队列的尾部添加元素并从头部删除它们,因此只要不须要知道队列的大 小,ConcurrentLinkedQueue 对公共集合的共享访问就能够工做得很好。收集关于队列大小的信息会很慢,须要遍历队列。数据结构
二、实现阻塞接口的:
java.util.concurrent 中加入了 BlockingQueue 接口和五个阻塞队列类。它实质上就是一种带有一点扭曲的 FIFO 数据结构。不是当即从队列中添加或者删除元素,线程执行操做阻塞,直到有空间或者元素可用。
五个队列所提供的各有不一样:并发
三、主要方法:app
add 增长一个元索 若是队列已满,则抛出一个IIIegaISlabEepeplian异常
remove 移除并返回队列头部的元素 若是队列为空,则抛出一个NoSuchElementException异常
element 返回队列头部的元素 若是队列为空,则抛出一个NoSuchElementException异常
offer 添加一个元素并返回true 若是队列已满,则返回false
poll 移除并返问队列头部的元素 若是队列为空,则返回null
peek 返回队列头部的元素 若是队列为空,则返回null
put 添加一个元素 若是队列满,则阻塞
take 移除并返回队列头部的元素 若是队列为空,则阻塞ide
四、四种队列详解函数
(1)LinkedBlockingQueue的容量是没有上限的(说的不许确,在不指定时容量为Integer.MAX_VALUE,不要然的话在put时怎么会受阻呢),可是也能够选择指定其最大容量,它是基于链表的队列,此队列按 FIFO(先进先出)排序元素。性能
(2)ArrayBlockingQueue在构造时须要指定容量, 并能够选择是否须要公平性,若是公平参数被设置true,等待时间最长的线程会优先获得处理(其实就是经过将ReentrantLock设置为true来 达到这种公平性的:即等待时间最长的线程会先操做)。一般,公平性会使你在性能上付出代价,只有在的确很是须要的时候再使用它。它是基于数组的阻塞循环队 列,此队列按 FIFO(先进先出)原则对元素进行排序。ui
(3)PriorityBlockingQueue是一个带优先级的 队列,而不是先进先出队列。元素按优先级顺序被移除,该队列也没有上限(看了一下源码,PriorityBlockingQueue是对 PriorityQueue的再次包装,是基于堆数据结构的,而PriorityQueue是没有容量限制的,与ArrayList同样,因此在优先阻塞 队列上put时是不会受阻的。虽然此队列逻辑上是无界的,可是因为资源被耗尽,因此试图执行添加操做可能会致使 OutOfMemoryError),可是若是队列为空,那么取元素的操做take就会阻塞,因此它的检索操做take是受阻的。另外,往入该队列中的元 素要具备比较能力。
(4)DelayQueue(基于PriorityQueue来实现的)是一个存放Delayed 元素的无界阻塞队列,只有在延迟期满时才能从中提取元素。该队列的头部是延迟期满后保存时间最长的 Delayed 元素。若是延迟都尚未期满,则队列没有头部,而且poll将返回null。当一个元素的 getDelay(TimeUnit.NANOSECONDS) 方法返回一个小于或等于零的值时,则出现期满,poll就以移除这个元素了。此队列不容许使用 null 元素.
五、代码例子
package is.data.structure.queue; import java.time.Duration; import java.time.Instant; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingDeque; /** * @ClassName: FruitBasket * @Description: * 水果篮子 * @Author: Coding_wxb */ public class FruitBasket { private boolean close = false; BlockingQueue<Fruit> basket = new LinkedBlockingDeque<>(10); //存放水果 public void storeFruit(Fruit fruit) throws InterruptedException{ basket.put(fruit); } //取出水果 public Fruit getFruit() throws InterruptedException{ return basket.take(); } //获取篮子中的水果数量 public int getSize(){ return basket.size(); } //水果生产者 class Producer implements Runnable{ @Override public void run() { try { while (!close){ System.out.println("生产者开始生产水果:"); Instant start = Instant.now(); Fruit fruit1 = new Fruit("read","apple"); Fruit fruit2 = new Fruit("yellow","pear"); storeFruit(fruit1); storeFruit(fruit2); Instant end = Instant.now(); System.out.println("生产水果总耗时:"+Duration.between(start,end).toMillis()); System.out.println("生产完水果,篮子中有:"+getSize()+"个水果"); Thread.sleep(3000); } }catch (Throwable e){ e.printStackTrace(); } } } //水果消费者 class Consumer implements Runnable{ @Override public void run() { try { while (!close){ System.out.println("消费者开始消费水果:"); Instant start = Instant.now(); Fruit fruit = getFruit(); System.out.println("这次消费水果为:"+fruit.toString()); System.out.println("生产完水果,篮子中有:"+getSize()+"个水果"); Instant end = Instant.now(); System.out.println("消费水果总耗时:"+Duration.between(start,end).toMillis()); Thread.sleep(3000); } }catch (Throwable e){ e.printStackTrace(); } } } public void test(){ ExecutorService ex = Executors.newCachedThreadPool(); Producer producer = new Producer(); Consumer consumer = new Consumer(); ex.submit(producer); ex.submit(consumer); //程序运行十秒结束 try { Thread.sleep(10000); }catch (Throwable e){ e.printStackTrace(); } ex.shutdownNow(); } public static void main(String[] args) { FruitBasket basket = new FruitBasket(); basket.test(); } //水果类 class Fruit{ private String color; private String name; public Fruit(String color, String name) { this.color = color; this.name = name; } @Override public String toString() { return "Fruit{" + "color='" + color + '\'' + ", name='" + name + '\'' + '}'; } } }