SynchronousQueue源码阅读心得

SynchronousQueue(简写为SQ)
  1. 同步队列中,读线程与写线程只有相互匹配时才能完成一次完整的读写操作。而读与写的匹配依赖于TransferQueue或TransferStack中的transfer()
  2. SQ中重要的数据结构有TransferQueue和TransferStack,还有QNode。QNode里有isData,item,next等成员变量
  3. 全流程概要: 以put(Obj e)为例,我们放入e之后,transfer()首先根据e是否为空来判断e与TransferQueue中的QNode是否目的一致(目的指写或者读)。假设目的一致,就需要将以new QNode(e)加入到队列,否则就poll出对应的QNode来完成写读一致性操作。
  4. TransferQueue中transfer(obj e)解析
    1. 主题是一个for(;;)循环,根据Queue中QNode的目的是否和当前操作一致来确定进入哪一个分支。
    2. 如果一致或队列为空的话
      1. 首先检验是否有不一致读的情况,即其他线程对队列进行操作(这里是由cas操作来控制并发,所以存在线程不安全的隐患)。再判断拖尾现象,即当前tail不是真正tail(仍有next)。上述两种边界条件都会continue。
      2. 随后会将新构建的QNode s插入到tail后,然后调用advanceTail()来更新tail节点。
        1. advanceTail(t, nt)函数将nt置为tail。但与之功能类似的advanceHead()会多一步操作,即在cas之后给old head加上h.next=h,从而避免garbage retention。
      3. 更新完后,会调用awaitFulfill()函数等待队列中QNode被match到。这里也是一个基于自旋锁类似的设置。
        1. awaitFullfill()函数首先会设置一个spins变量,可以理解为自旋次数,不过次数的设置条件不是很了解。然后就是一个经典的for(;;)循环(在并发场景中这种格式的循环频频出现),在循环体内,首先就是一个判断current thread是否被interrupt的if,如果if成立,就会调用tryCancle函数来将QNode s取消。
          1. tryCancel()解析
            1. 本方法多用于awaitFullFill()中(基于UNSAFE.compareAndSwapObject())
            2. 如果一个QNode被tryCancel了,那么its item will ref itself.
      4. 上述if不成立的话,会判断s.item与tranfer的目标对象e是否相同,如果不同就会返回s.item。这里就会引出transfer()(line 696)函数中的一个if逻辑。然后会根据spins是否大于0,来continue for-loop,如果不成立就会park住当前的thread。(这里其实有一个锁升级的场景)
        1. if(x==s)(line 696)这个条件是来源于如果s被cancle了,那么s.item就等于s,而返回值x等于s.item,所以x=s
      5. 如果4中if逻辑成立,那么会对queue进行clean,即clean掉QNode s。假设不成立,会判断s是否OffList,如果没有的话,就说明s没有unlink掉,那么我们需要将其unlink掉。
        1. OffList()是判断当前QNode的next是否指向它本身,如果指向它本身的话,说明被advanceHead了。
      6. 最后返回item
    3. 如果目的不一致
      1. 在过滤掉不一致的场景后,我们直接将head QNode(实际上是head.next,但为了方便理解,这里统一使用head QNode)给advanceHead掉,然后unpark head QNode对应的线程,并返回item值。
        1. 这里值得熟记的一点就是line 714对应的if逻辑,这里主要判断了目标是否被完成,head QNode有没有被cancle,以及有没有成功cas headNode(Cas(head, head.next))。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值