JDK1.8源码解析之SynchronousQueue

SynchronousQueue源码解析

  • 前言
    这是一个阻塞队列,每一个线程的插入操作都要等待另一个对应的删除操作。这个同步队列没有任何的容量,甚至没有一个元素的容量。你不能查看同步队列中的元素,因为想要查看一个元素必须是在正在尝试删除一个元素的时候。你不能向队列中插入元素,除非有另外一个线程正在删除队列中的元素。这个队列不能使用迭代器迭代遍历元素,因为这个同步队列中没有元素可以遍历。它们非常适合于切换设计,在这种设计中,在一个线程中运行的对象必须与在另一个线程中运行的对象同步,以便传递一些信息、事件或任务。这个队列支持可选的公平策略对生产者线程池和消费者线程排序,默认情况下是非公平策略,设置了公平策略可以保证先进先出的顺序。
    在这里插入图片描述
    非公平策略和公平策略的执行形式基本上是一样的,非公平策略队列用的是stack(Lifo后进先出),公平策略队列用的是queue(Fifo先进先出),先进先出队列在竞争下通常支持更高的吞吐量,但是Lifo在公共应用程序中维护更高的线程局部性。
    公平策略和非公平策略的队列都继承了一个静态抽象内部类Transferer,两种策略都要实现transfer方法。
    先来看看非公平策略模式
    非公平策略的stack中的节点使用是SNode,来看一下这个静态内部类?

SNode的变量

volatile SNode next;        // next node in stack
volatile SNode match;       // the node matched to this
volatile Thread waiter;     // to control park/unpark
Object item;                // data; or null for REQUESTs
int mode;

FIFO类型的SynchronousQueue的执行流程
在这里插入图片描述
FIFO源码比较简单,这里就不在介绍,LIFO类型的就是比较饶了,我是琢磨了一段时间才弄明白,不同的任务之间是如何进行匹配的,并且在匹配过程中是如何完成数据传递的。
这里先直接上代码,讲解完代码之后,在总结一个流程图,加油,相信自己只有熬过最难熬的过程,说明你才有机会进步。
LIFO的意思使用的是栈的数据结构,所有具有后进先出的效果。
LIFO的主类是TransferStack,
有4个重要的变量:
在这里插入图片描述
这三个变量用来表示栈中节点SNODE的模式,REQUEST 表示请求获取数据的操作,DATA 表示想队列中添加数据的操作,FULFILLING 表示当前SNODE正在匹配的过程中,希望其他线程不要干扰。
嗨皮猫
这个变量是栈的头结点,这里使用的是volatile,在多线程并发的环境下实现同步,对多线程保持可见性。
在来看看栈中节点的数据结构是啥样的?
来自csdn的嗨皮猫
在来看看核心方法transfer(),由于代码比较长,所以这里分三种情况进行解析。

  1. 当前栈为空或者当前的节点的模式和head节点的模式相同,那么当前节点入栈等待匹配。
    来自csdn的嗨皮猫
  2. 当前节点和head节点的模式是互补的,也就是说一个节点是到栈取元素的,一个节点是到栈添加元素的节点,判断这两个节点互补的方法是isFulfilling(int),先来看看这个是如何实现的?
    在这里插入图片描述
    m是NODE的模式,只有三种0 、1、2
    看一下计算结果:
    0 & 2 即 0000 & 0010 = 0000 = 0
    1 & 2 即 0001 & 0010 = 0000 = 0
    2 & 2 即 0010 & 0010 = 0010 = 2
    所以 isFulfilling 只有m=2时,才会返回true,这个标志位的作用是显示的表明当前节点正在完成匹配,其他线程请勿干扰。
    需要注意的地方就是,当当前节点正处于匹配的时候,这个时候当前节点的模式的计算公式如下:
    在这里插入图片描述
    计算结果如下:
    0 | 2 即 0000 | 0010 = 0010 = 2
    1 | 2 即 0001 | 0010 = 0011 = 3
    2 | 2 即 0010 | 0010 = 0010 = 2
    接下来就可以解析源码啦?有点困了,额,在加把劲!!!
    在这里插入图片描述
    最后看一看,node进入阻塞是怎么处理的?
    在这里插入图片描述
    整个LIFO的transfer至此已经完成,JDK1.8源码解析又完成了一个,开始进入下一个吧!!!
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值