在新增呢的concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题,通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利;
常用的队列主要由以下两种:
1.先进先出(FIFO):先插入的队列的元素也最先出队列,类似于排队的功能,从某种程度上来说这种队列也体现了一种公平性;
2.后进后出(LIFO):后插入队列的元素最先出队列,这种队列优先处理最近发生的事件;
20.1 ArrayBlockingQueueArrayBlockingQueue是一个有边界的阻塞队列,它的内部实现是一个数组,有边界意思就是它的容量是有限的,我们必须在其初始化的时候执行它的容量大小,容量大小一旦执行就不可改变;
ArrayBlockingQueue是以先进先出的方式存储数据,最新插入的对象是尾部,最新移除的对象是头部;
public class ArrayBlockingQueueTest { public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<String> arrays=new ArrayBlockingQueue<String>(3); arrays.add("张三"); arrays.add("李四"); arrays.add("王五"); //添加阻塞队列 arrays.offer("赵六",1, TimeUnit.SECONDS); //poll方法相当于消费了队列中的数据,队列的数据就会删除 System.out.println(arrays.poll()); System.out.println(arrays.poll()); System.out.println(arrays.poll()); System.out.println(arrays.poll()); } }
如果先出队一条数据,此时被阻塞的数据就可以添加进来
public class ArrayBlockingQueueTest { public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<String> arrays=new ArrayBlockingQueue<String>(3); arrays.add("张三"); arrays.add("李四"); arrays.add("王五"); System.out.println(arrays.poll()); //添加阻塞队列 arrays.offer("赵六",1, TimeUnit.SECONDS); //poll方法相当于消费了队列中的数据,队列的数据就会删除 System.out.println(arrays.poll()); System.out.println(arrays.poll()); System.out.println(arrays.poll()); } }
20.2 LinkedBlockingQueue
LinkedBlockingQueue阻塞队列大小的配置时可选的,如果我们初始化时指定大小,它就是有边界的,如果不指定,它就是无边界的。说是无边界,其实是采用了默认大小为Integer.MAX_VALUE容量,它的内部是一个链表;
和ArrayBlockingQueue一样,LinkedBlockingQueue也是以先进先出的方式存储数据,最新插入的对象是尾部,最新移除的对象是头部;
public class LinkedBlockingQueueTest { public static void main(String[] args) throws InterruptedException { LinkedBlockingQueue linkedBlockingQueue=new LinkedBlockingQueue(3); linkedBlockingQueue.add("A"); linkedBlockingQueue.add("B"); linkedBlockingQueue.add("C"); System.out.println(linkedBlockingQueue.poll()); System.out.println(linkedBlockingQueue.size()); } }
20.3 PriorityBlockingQueue
PriorityBlockingQueue是一个没有边界的队列,它的排序规则和java.util.PriorityQueue一样。需要注意,PriorityBlockingQueue中国允许插入null对象;
所有插入PriorityBlockingQueue的对象必须实现java.lang.Comparable接口,队列优先级的排序规则就是按照我们对这个接口的实现来定义的;
另外,我们可以从PriorityBlockingQueue获得一个迭代器Iterator,但这个迭代器并不保证按照优先级顺序进行迭代;
public class PriorityBlockingQueueTest { public static void main(String[] args) throws InterruptedException { PriorityBlockingQueue<String> priorityBlockingQueue=new PriorityBlockingQueue<String>(3); priorityBlockingQueue.add("AA"); priorityBlockingQueue.add("BB"); priorityBlockingQueue.add("CC"); System.out.println(priorityBlockingQueue.poll()); System.out.println(priorityBlockingQueue.size()); } }
20.3 SynchronousQueue