ArrayBlockingQueue源码解析
本文仅为本人学习记录,如有错误还请不吝斧正!
ArrayBlockingQueue在实例化的时候创建了两个条件队列notEmpty和notFull两个条件队列,这两个队列公用一把ReentrantLock锁
两个队列均为单向队列,由firstNode和lastNode指针指向首尾,节点为node节点(AQS ReentrantLock知识此处不做赘述)
阻塞队列实例化完成之后,我们就可以开启线程进行put和take操作,本文主讲put方法,take
方法基本相似,无非是一个入队一个出队。
首先我们看看put方法源码:
先获取锁,此处为什么要用while呢? 若数组中数量已经达到阻塞队列长度则将线程阻塞,若数量未达上限
则执行入队操作,我们先看简单的入队enqueue方法源码
可以看到没有什么逻辑,直接将值放入数组中,最后发送信号给notEmpty条件队列,可以将队列节点
唤醒,将节点waitStatus状态从-2改为0,将node节点放入同步队列CLH中。
接着看await方法
1.Thread.interrupted() 若线程被中断则抛出中断异常。
2.addConditionWaiter()方法,新建一个节点,若队列中已有节点,则将lastWaiter节点next指针指向新建
node节点,lastWaiter节点指向node节点。
3.fullyRelease(node)释放锁,代码逻辑unlock方法基本一致。
4.isOnSyncQueue(node) 这里不断循环查看节点是否存在于同步CLH队列中是否存在,若存在将该线程
进行阻塞,直到被唤醒。
5.接下来就是被唤醒,重新去获取锁,执行后续逻辑