LinkedBlockQueue自JDK1.5以后提供的一种阻塞队列,遵循生产者消费者模式,实现了BlockQueue接口,如图

LinkedBlockQueue生产消费源码解析 随笔 第1张

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

从它的名字可以了解到它是采用链表的方式实现了阻塞队列,并且定义了“节点”的内部类,如图

LinkedBlockQueue生产消费源码解析 随笔 第2张

我们看到,每个Node当中除了Node的数据item以外只有一个next节点来指向下一个节点。

另外LinkedBlockQueue在实现里采用了ReentrantLock来控制生产和消费等操作的并发情况,并且采用关联的Condition来做阻塞等待,所以它是线程安全的。

LinkedBlockQueue生产消费源码解析 随笔 第3张

DEMO

接下来,我们把LinkedBlockQueue的DEMO作为入口,代码如下

LinkedBlockQueue生产消费源码解析 随笔 第4张

构造方法

构造方法允许指定队列最大容量,如果不指定则采用INT的最大值。所以LinkedBlockQueue实际上也属于有界队列,只是它的默认队列容量很大,一般情况下不会出现超过容量的情况。

LinkedBlockQueue生产消费源码解析 随笔 第5张

LinkedBlockQueue定义了head和last节点分别表示起始和结束,是一种双端链表的实现方式,head的item永远为null,last的next永远为null,当队列为空的时候head节点和last节点指向一个空的Node

LinkedBlockQueue生产消费源码解析 随笔 第6张

生产操作offer(E e)

offer(E e)方法仅提供一个数据入参,如果容量未满则入队,如果满了那么直接结束。

 LinkedBlockQueue生产消费源码解析 随笔 第7张

入队方法很简单,就是将当前最后一个节点的next指向新的节点,并且新的节点成为最后一个节点

LinkedBlockQueue生产消费源码解析 随笔 第8张

生产操作offer(E e, long timeout, TimeUnit unit)

该方法与普通offer方法的区别在于提供了超时时间,也就是说在没有空间可以增加元素的时候会进行阻塞等待,这里采用Condition的方式实现

LinkedBlockQueue生产消费源码解析 随笔 第9张

生产操作put(E e)

put方法跟offer的区别在于,如果没有足够的空间put会一直等待直到中断或者有空间

LinkedBlockQueue生产消费源码解析 随笔 第10张

消费操作poll()

poll操作不会进行等待,如果没有待消费的元素,那么直接返回

LinkedBlockQueue生产消费源码解析 随笔 第11张

出队操作就是把当前的第一个head节点的next指向自己,真正的第一个node节点成为head节点

LinkedBlockQueue生产消费源码解析 随笔 第12张

消费操作poll(long timeout, TimeUnit unit)

如果没有待消费的数据,该方法会进行等待,直到有消费数据或者中断

LinkedBlockQueue生产消费源码解析 随笔 第13张

 消费操作take()

跟put类似take是一个会一直等待的操作,如果没有待消费的数据那么就阻塞直到中断或者消费到数据

LinkedBlockQueue生产消费源码解析 随笔 第14张

LinkedBlockQueue在的生产和消费操作是通过互斥锁来控制并发的,也就是同时只会有一个生产操作或者一个消费操作,当生产操作完成会通知等待消费线程,消费操作完成会通知等待生产的线程。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄