队列是我们在开发中经常会使用到的一种数据结构,并且在多线程资源共享与数据协调的场景中,队列也是我们最喜欢的选择之一,尤其是在生产者与消费者模型中。下面我们就介绍一下在java中常用的BlockingQueue家族队列。
BlockingQueue家族(常用系列)
BlockingQueue,顾名思义即是阻塞队列,意指再读取和插入操作情况下可能(注意是可能)会出现阻塞。
BlockingQueue本身是一个接口,主要定义了关于队列的各类操作方法,当发生无法继续入队或者无数据可以读出的时候,会发生如下图所示的情况。其中Special Value为true或者false,Blocks的方法会发生阻塞,Throws Exception列内的方法会抛出异常,Times Out指超过设定时间则会按照Special Value类型的方法返回true或者false。
BlockingQueue本身只是一个接口,具体的实现交由其实现类进行定义设计,本篇主要简单介绍一下几个类,相信各位读者大大在掌握以下几个类的使用之后,便能应对大多数场景了
-
ArrayBlockingQueue
-
LinkedBlockingQueue
-
SynchronousQueue
-
PriorityBlockingQueue
-
DelayQueue
ArrayBlockingQueue
ArrayBlockingQueue,相信大家看名字就能猜到,改阻塞队列是基于数据实现的,同时使用ReentrantLock来实现并发问题的解决。同时需要注意的是ArrayBlockingQueue只要一把锁,put和get操作会相互阻塞。我们看一下其构造函数即可清楚知道
LinkedBlockingQueue
LinkedBlockingQueue和ArrayBlockingQueue十分相似,其底层是借由链表实现。除此之外,还有一个不同点,LinkedBlockingQueue拥有两个锁,因此put和get的线程可以同时运行
SynchronousQueue
SynchronousQueue的特点是只能容纳一个元素,同时SynchronousQueue使用了两种模式来管理元素,一种是使用先进先出的队列,一种是使用后进先出的栈,使用哪种模式可以通过构造函数来指定。
PriorityBlockingQueue
PriorityBlockingQueue顾名思义,按照优先级排序且无边界的队列。插入其中的元素必须实现java.lang.Comparable接口。其排序规则就按此实现。
DelayQueue
DelayQueue即为延迟队列,使得插入其中的元素在延迟一定时间后,才能获取到,插入其中的元素需要实现java.util.concurrent.Delayed接口。该接口需要实现getDelay()和compareTo()方法。getDealy()返回0或者小于0的值时,delayedQueue通过其take()方法就可以获得此元素。compareTo()方法用于实现内部元素而的排序,一般情况,按元素过期时间的优先级进行排序是比较好的选择。下面我们通过一个示例来演示一下DelayQueue的使用