并发编程 - 阻塞队列 - SynchronousQueue (非公平模式)

TransferStack

非公平模式基于栈的FILO(先进后出)的思想。transfer(…) 方法的三种判断处理,是其TransferStack的核心。

源码解析

属性:
并发编程 - 阻塞队列 - SynchronousQueue (非公平模式)_第1张图片

在这里插入图片描述

并发编程 - 阻塞队列 - SynchronousQueue (非公平模式)_第2张图片

方法:

  1. 判断是否是互补模式。
    在这里插入图片描述

  2. cas方式设置头节点。
    在这里插入图片描述

  3. 创建或者重置节点的属性。
    并发编程 - 阻塞队列 - SynchronousQueue (非公平模式)_第3张图片

  4. 如果节点s是头节点或者头节点为空或者头节点的模式是互补模式,返回true。(是否应该自旋)
    并发编程 - 阻塞队列 - SynchronousQueue (非公平模式)_第4张图片

  5. 断开节点与栈的连接。

        void clean(SNode s) {
            s.item = null;   
            s.waiter = null; 
            SNode past = s.next;
            if (past != null && past.isCancelled())
                past = past.next;

            SNode p;
            /* 对于取消状态的头节点,cas方式将头节点的后继节点设置新的头节点,直到给定节点的后继节点为止 */
            while ((p = head) != null && p != past && p.isCancelled())
                casHead(p, p.next);

            /* 头节点的后继节点如果为空,cas方式设置新的后继节点,直到给定节点的后继节点为止 */
            while (p != null && p != past) {
                SNode n = p.next;
                if (n != null && n.isCancelled())
                    p.casNext(n, n.next);
                else
                    p = n;
            }
        }

通过上面的代码,可以看出,除了清理给定节点s,还会从头节点开始到给定节点的后继节点,断开被取消的节点在栈中的连接。

  1. 自旋或者阻塞直到一个节点被匹配。 (等待匹配)(根据timed的值决定使用自旋还是阻塞)
        SNode awaitFulfill(SNode s, boolean timed, long nanos) {
            final long deadline = timed ? System.nanoTime() + nanos : 0L;
            Thread w = Thread.currentThread();
            int spins = (shouldSpin(s) ?
                         (timed ? maxTimedSpins : maxUntimedSpins) : 0);
            for (;;) {
                if (w.isInterrupted())
                    s.tryCancel();
                SNode m = s.match;
                /* 得到了匹配 */
                if (m != null)
                    return m;
                if (timed) {
                    nanos = deadline - System.nanoTime();
                    /* 超时 */
                    if (nanos <= 0L) {
                        s.tryCancel();
                        continue;
                    }
                }
                if (spins > 0)
                    spins = shouldSpin(s) ? (spins-1) : 0;
                /* 节点入栈,设置waiter为当前线程 */
                else if (s.waiter == null)
                    s.waiter = w; 
                else if (!timed)
                    LockSupport.park(this);
                else if (nanos > spinForTimeoutThreshold)
                    LockSupport.parkNanos(this, nanos);
            }
        }
  1. 转移元素 (pop or push)
        E transfer(E e, boolean timed, long nanos) {
            SNode s = null; 
            /* 元素为空表示消费模式,反之表示生产模式 */
            int mode = (e == null) ? REQUEST : DATA;
            for (;;) {
                SNode h = head;
                /* 1. 栈为空或者节点与栈里已有节点的模式相同 */
                if (h == null || h.mode == mode) {  
                    if (timed && nanos <= 0) {     
                        if (h != null && h.isCancelled())
                        	/* 如果头节点存在,并且被取消了,就设置新的头节点 */
                            casHead(h, h.next);    
                        else
                        	/* 栈为空 */
                            return null;
                    /* 设置新的头节点,也就是将节点s入栈 */
                    } else if (casHead(h, s = snode(s, e, h, mode))) {
                    	/* 指定超时时间内等待匹配 */
                        SNode m = awaitFulfill(s, timed, nanos);
                        /* 等待的过程中被取消 */
                        if (m == s) {              
                            clean(s);
                            return null;
                        }
                        /* 匹配成功 */
                        if ((h = head) != null && h.next == s)
                        	/* 匹配成功的话,将新的栈顶节点与匹配的节点s同时执行出栈操作,所以选取节点s的后继节点为新的头节点 */
                            casHead(h, s.next);     // help s's fulfiller
                        return (E) ((mode == REQUEST) ? m.item : s.item);
                    }
                /* 2. 节点与栈里已有节点的模式不相同,并且栈顶节点的模式不是互补模式 */
                } else if (!isFulfilling(h.mode)) { 
                    if (h.isCancelled())           
                        casHead(h, h.next);        
                    /* 将节点s入栈,也就是栈顶,并且将它的模式与fulfilling按位或 */
                    /* 按位或,保留了原有的模式 */ 
                    else if (casHead(h, s=snode(s, e, h, FULFILLING|mode))) {
                        for (;;) { 
                            SNode m = s.next;       
                            if (m == null) {        
                                casHead(s, null);   
                                s = null;           
                                break;             
                            }
                            SNode mn = m.next;
                            /* 如果节点s和它的后继节点m匹配成功 */
                            if (m.tryMatch(s)) {
                            	/* 将m的后继节点mn设置为新的头节点 */
                            	/* pop both s and m */
                                casHead(s, mn);     
                                return (E) ((mode == REQUEST) ? m.item : s.item);
                            /* 如果匹配失败,将节点m取消在栈中的连接 */
                            } else                  
                                s.casNext(m, mn);   
                        }
                    }
                /* 3. 节点与栈里已有节点的模式不相同,并且栈顶节点的模式是互补模式 -> used to help a fulfiller */
                } else { 
                	/* m是h的匹配 */                          
                    SNode m = h.next;  
                    /* waiter is gone */            
                    if (m == null)        
                    	/* pop fulfilling node */         
                        casHead(h, null);          
                    else {
                        SNode mn = m.next;
                        if (m.tryMatch(h))         
                            casHead(h, mn);         
                        else                        
                            h.casNext(m, mn);      
                    }
                }
            }
        }

参考TransferStack的分析:

你可能感兴趣的:(多线程)