SynchronousQueue源码解析(公平模式)

上篇文章中,画图解释了,SynchronousQueue 的工作原理。

这篇文章,详细的解析源码(图解 SynchronousQueue原理)。

默认你已经读了上篇文章,这篇文章重点说源码。以公平模式为例

一、初始化

	SynchronousQueue<Integer> queue = new SynchronousQueue<>(true);

    public SynchronousQueue(boolean fair) {
   
        transferer = fair ? new TransferQueue<E>() : new TransferStack<E>();
    }

      TransferQueue() {
   
         QNode h = new QNode(null, false); // initialize to dummy node.
         head = h;
         tail = h;
      }

公平模式,底层是队列来实现的,看下这个内部类 TransferQueue,有这四个属性

            volatile QNode next;          // next node in queue
            volatile Object item;         // CAS'ed to or from null
            volatile Thread waiter;       // to control park/unpark
            final boolean isData;

初始化之后,大概就像下面这张图

在这里插入图片描述

二、调用 put() 会阻塞

用上篇文章中的例子, t1, t2, t3 先后往队列中放 10, 20, 30。

    public void put(E e) throws InterruptedException {
   
        if (e == null) throw new NullPointerException();
        if (transferer.transfer(e, false, 0) == null) {
   
            Thread.interrupted();
            throw new InterruptedException();
        }
    }

也就是说 put(e) 方法,会调用 transferer.transfer(e, false, 0)

多说一句,取元素与放元素都会调用这个 transfer 方法,只是参数不同而已。

在这里插入图片描述
这是三个线程操作之后 QNode 队列,结合图,来说源码。

       E transfer(E e, boolean timed, long nanos) {
   
            QNode s = null; // constructed/reused as needed
            boolean isData = (e != null);
            for (;;) {
   
                QNode t = tail;
                QNode h = head;
                if (t == null || h == null)         // saw uninitialized value
                    continue;                       // spin

                if (h == t || t.isData == isData) {
    // empty or same-mode
                    QNode tn = t.next;
                    if (t != tail)                  // inconsistent read
                        continue;
                    if (tn != null) {
                  // lagging tail
                        advanceTail(t, tn);
                        continue;
                    }
                    if (timed && nanos <= 0)        // can't wait
                        return null;
                    if (s == null)
                        s = new 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值