Phaser

 

package java.util.concurrent;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.LockSupport;


public class Phaser {
   
    private volatile long state;

    private static final int  MAX_PARTIES     = 0xffff;
    private static final int  MAX_PHASE       = Integer.MAX_VALUE;
    private static final int  PARTIES_SHIFT   = 16;
    private static final int  PHASE_SHIFT     = 32;
    private static final int  UNARRIVED_MASK  = 0xffff;      // to mask ints
    private static final long PARTIES_MASK    = 0xffff0000L; // to mask longs
    private static final long COUNTS_MASK     = 0xffffffffL;
    private static final long TERMINATION_BIT = 1L << 63;

    // some special values
    private static final int  ONE_ARRIVAL     = 1;
    private static final int  ONE_PARTY       = 1 << PARTIES_SHIFT;
    private static final int  ONE_DEREGISTER  = ONE_ARRIVAL|ONE_PARTY;
    private static final int  EMPTY           = 1;

    // The following unpacking methods are usually manually inlined

    //未到达数(低16位)
    private static int unarrivedOf(long s) {
        int counts = (int)s;
        return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
    }

    //参与数
    private static int partiesOf(long s) {
        return (int)s >>> PARTIES_SHIFT;
    }

    //阶段数
    private static int phaseOf(long s) {
        return (int)(s >>> PHASE_SHIFT);
    }

    //已到达数(参与数-未到达数)
    private static int arrivedOf(long s) {
        int counts = (int)s;
        return (counts == EMPTY) ? 0 :
            (counts >>> PARTIES_SHIFT) - (counts & UNARRIVED_MASK);
    }

    //父实例,当子实例全部到达时,父实例到达数加1
    private final Phaser parent;

    //最顶层实例,如果只有一个实例,那么root指向自身
    //一个线程被挂起时,节点信息总是存放到root的等待队列中
    //唯有root可以执行onAdvance方法子实例无效,为有root的未到达数为0才执行onAdvance
    //子实例全部到达时只会递减父未达到数1次
    private final Phaser root;

    //为了性能考虑使用两个队列,当阶段数phase为偶数是使用evenQ,否则oddQ
    private final AtomicReference<QNode> evenQ;
    private final AtomicReference<QNode> oddQ;

    //当前阶段值是偶数返回队列evenQ否则返回oddQ
    private AtomicReference<QNode> queueFor(int phase) {
        return ((phase & 1) == 0) ? evenQ : oddQ;
    }


    private String badArrive(long s) {
        return "Attempted arrival of unregistered party for " +
            stateToString(s);
    }


    private String badRegister(long s) {
        return "Attempt to register more than " +
            MAX_PARTIES + " parties for " + stateToString(s);
    }

    //被arrive与arriveAndDeregister调用的方法
    // arrive使用doArrive(1)将未到达数减1
    //arriveAndDeregister使用doArrive(1 << 16 | 1)解除一个参与者
    private int doArrive(int adjust) {//adjust为要重state减去的值
        final Phaser root = this.root;
        for (;;) {
            //reconcileState保持父子实例的阶段数一致,并返回当前实例的state
            long s = (root == this) ? state : reconcileState();
            int phase = (int)(s >>> PHASE_SHIFT);
            if (phase < 0)//使用在调用了onAdvance是返回true进行了终止
                return phase;
            int counts = (int)s;
            int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);
            if (unarrived <= 0)//已全部到达,不允许再调用arrive方法
                throw new IllegalStateException(badArrive(s));
            if (UNSAFE.compareAndSwapLong(this, stateOffset, s, s-=adjust)) {//比较递减,失败会自旋重试
                //如果当前是最后一个未到达,那么检查是否可以执行栅栏方法onAdvance
                if (unarrived == 1) {
                    long n = s & PARTIES_MASK;  // 0xffff0000L
                    int nextUnarrived = (int)n >>> PARTIES_SHIFT;
                    if (root == this) {//是顶层实例直接执行onAdvance
                        if (onAdvance(phase, nextUnarrived))
                            n |= TERMINATION_BIT;//1L << 63最高位设1,变成负数
                        else if (nextUnarrived == 0)
                            n |= EMPTY;
                        else
                            n |= nextUnarrived;
                        int nextPhase = (phase + 1) & MAX_PHASE;
                        n |= (long)nextPhase << PHASE_SHIFT;
                        //phase递增,未到达数更新为参与数
                        UNSAFE.compareAndSwapLong(this, stateOffset, s, n);
                        //唤醒所有线程
                        releaseWaiters(phase);
                    }
                    else if (nextUnarrived == 0) { // propagate deregistration
                        //如果子phaser参与者全部解除,那么父节点参与者递减1
                        phase = parent.doArrive(ONE_DEREGISTER);
                        UNSAFE.compareAndSwapLong(this, stateOffset,
                                                  s, s | EMPTY);
                    }
                    //子phaser全部到达调用父实例的doArrive(1)
                    else
                        phase = parent.doArrive(ONE_ARRIVAL);
                }
                return phase;
            }
        }
    }

    //由register, bulkRegister调用,注册参与者
    private int doRegister(int registrations) {
        // adjustment to state
        // state要调整的值,同时增加参与数parties与未到达数unarrived
        long adjust = ((long)registrations << PARTIES_SHIFT) | registrations;
        final Phaser parent = this.parent;
        int phase;
        for (;;) {
            long s = (parent == null) ? state : reconcileState();
            int counts = (int)s;
            //取得paties数与unarrived
            int parties = counts >>> PARTIES_SHIFT;
            int unarrived = counts & UNARRIVED_MASK;
            //总parties数不能超过16位65535
            if (registrations > MAX_PARTIES - parties)
                throw new IllegalStateException(badRegister(s));
            phase = (int)(s >>> PHASE_SHIFT);
            //阶段数小于0说明已经终止
            if (phase < 0)
                break;
            if (counts != EMPTY) {//如果不是第一次注册,则检查是不是在执行onAdvance()
                if (parent == null || reconcileState() == s) {
                    //unarrived等于0说明全部到达需要等待onAdvance()执行完毕
                    if (unarrived == 0)             // wait out advance
                        //等待onadvance执行完成
                        //如果执行完成,那么phase与实际state的phase的值不同此方法直接返回,重新执行for循环
                        //否则会将当前线程放到等待队列,等onAdvance执行结束后会释放所有线程
                        root.internalAwaitAdvance(phase, null);
                    //否则就修改state的值,增加adjust,注册成功则跳出循环并返回
                    else if (UNSAFE.compareAndSwapLong(this, stateOffset,
                                                       s, s + adjust))
                        break;
                }
            }
            //第一次注册且是顶层phaser实例
            else if (parent == null) {              // 1st root registration
                long next = ((long)phase << PHASE_SHIFT) | adjust;
                //注册成功则跳出循环并返回
                if (UNSAFE.compareAndSwapLong(this, stateOffset, s, next))
                    break;
            }
            else {
                synchronized (this) {               // 1st sub registration
                    //当前子phaser是第一次注册parties,那么父phaser的parties加1
                    if (state == s) {               // recheck under lock
                        phase = parent.doRegister(1);
                        if (phase < 0)
                            break;
                        // finish registration whenever parent registration
                        // succeeded, even when racing with termination,
                        // since these are part of the same "transaction".
                        while (!UNSAFE.compareAndSwapLong
                               (this, stateOffset, s,
                                ((long)phase << PHASE_SHIFT) | adjust)) {
                            //比较设置失败继续尝试,phase始终与root的同步
                            s = state;
                            phase = (int)(root.state >>> PHASE_SHIFT);
                            // assert (int)s == EMPTY;
                        }
                        break;
                    }
                }
            }
        }
        return phase;
    }

    //保持子phaser与顶层phaser实例的phase一致
    //如果不一致需要保持一致并将未到达数重置为参与数
    private long reconcileState() {
        final Phaser root = this.root;
        long s = state;
        //如果当前phaser不是顶层实例,需要确保自己的阶段数phase与顶层的一致
        if (root != this) {
            int phase, p;
            // CAS to root phase with current parties, tripping unarrived
            while ((phase = (int)(root.state >>> PHASE_SHIFT)) !=
                   (int)(s >>> PHASE_SHIFT) &&//阶段数不一致才需要如下调整
                   !UNSAFE.compareAndSwapLong
                   (this, stateOffset, s,
                    s = (((long)phase << PHASE_SHIFT) |//将当前的phase设为顶层phase的值
                         ((phase < 0) ? (s & COUNTS_MASK) ://如果已终止,保持s的低32位不变(不调整)
                          (((p = (int)s >>> PARTIES_SHIFT) == 0) ? EMPTY ://中16位是0,说明没有参与者,设置为EMPTY
                           ((s & PARTIES_MASK) | p))))))//否则将未到达数也设置为参与数
                s = state;
        }
        return s;
    }

    //实例化一个顶层实例,参与数为0
    public Phaser() {
        this(null, 0);
    }

    //实例化一个顶层实例,参与数为parties
    public Phaser(int parties) {
        this(null, parties);
    }

    //实例化一个子实例,父实例为parent
    public Phaser(Phaser parent) {
        this(parent, 0);
    }

    //实例化一个实例并指定父实例已经子实例的参与数
    public Phaser(Phaser parent, int parties) {
        //parties数最大16位,也就是不超过65535个
        if (parties >>> PARTIES_SHIFT != 0)
            throw new IllegalArgumentException("Illegal number of parties");
        int phase = 0;
        this.parent = parent;
        //parent不为空需要调用parent的doRegister(1),且等待队列与root共用
        if (parent != null) {
            final Phaser root = parent.root;
            this.root = root;//树结构顶层的Phaser
            //复用顶层phaser的队列
            this.evenQ = root.evenQ;
            this.oddQ = root.oddQ;
            if (parties != 0)
                //只要子Phaser的parties不为0(无论多少),那么父phaser的paties加1
                phase = parent.doRegister(1);
        }
        else {
            this.root = this;
            this.evenQ = new AtomicReference<QNode>();
            this.oddQ = new AtomicReference<QNode>();
        }
        this.state = (parties == 0) ? (long)EMPTY :
            ((long)phase << PHASE_SHIFT) |//高32位存放阶段数
            ((long)parties << PARTIES_SHIFT) |//中间16存放参与者数
            ((long)parties);//低16位存放未到达数
    }

    //新增一个party参与者,为到达数也加1
    //返回大于等于0说明操作成功,否则说明phaser已结束
    public int register() {
        return doRegister(1);
    }

    //一次注册多个参与者
    public int bulkRegister(int parties) {
        if (parties < 0)
            throw new IllegalArgumentException();
        if (parties == 0)//parties为0返回阶段数
            return getPhase();
        return doRegister(parties);
    }

    //指示一个到达,非阻塞方法
    public int arrive() {
        return doArrive(ONE_ARRIVAL);
    }

    //指示一个到达,并且取消一个参与者,非阻塞方法
    public int arriveAndDeregister() {
        return doArrive(ONE_DEREGISTER);
    }

    //指示一个到达,并阻塞,直到全部到达
    public int arriveAndAwaitAdvance() {
        // Specialization of doArrive+awaitAdvance eliminating some reads/paths
        final Phaser root = this.root;
        for (;;) {
            //如果当前是子phaser,那么通过reconcileState方法检测子实例与父实例的阶段数是否一致
            //如果不一致,以父实例的值为准并且将子实例的未到达数重置为参与数,并返回子实例调整后的state值
            //如果一致,直接返回子实例的state值
            long s = (root == this) ? state : reconcileState();
            //取阶段数,高32位
            int phase = (int)(s >>> PHASE_SHIFT);
            //phase小于0说明已结束
            if (phase < 0)
                return phase;
            int counts = (int)s;//转化为int值(去除高32位)
            //取未到达数,低16位
            int unarrived = (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK);//0xffff
            if (unarrived <= 0)//未到达数为0时不允许再调用arrive相关方法
                throw new IllegalStateException(badArrive(s));
            //将未到达数递减1次
            if (UNSAFE.compareAndSwapLong(this, stateOffset, s,
                                          s -= ONE_ARRIVAL)) {
                //不是最后一个到达,进入自旋,自旋无果进入root的等待队中
                if (unarrived > 1)
                    return root.internalAwaitAdvance(phase, null);
                //如果当前phaser是最后一个到达
                //1.是顶层phaser那么调用onAdvance回调
                //2,是子phaser那么调用父phaser的arriveAndAwaitAdvance方法
                //由此可见,子phaser的onAdvance是没有机会调用的
                if (root != this)
                    return parent.arriveAndAwaitAdvance();
                //取中间的16位0xffff0000
                long n = s & PARTIES_MASK;  // base of next state
                //得到参与数
                int nextUnarrived = (int)n >>> PARTIES_SHIFT;
                //如果onAdvance返回true则终止
                if (onAdvance(phase, nextUnarrived))
                    n |= TERMINATION_BIT;
                else if (nextUnarrived == 0)
                    n |= EMPTY;
                else
                    n |= nextUnarrived;//恢复原来的值(重置未到达数)
                //将阶段数加1
                int nextPhase = (phase + 1) & MAX_PHASE;
                n |= (long)nextPhase << PHASE_SHIFT;
                if (!UNSAFE.compareAndSwapLong(this, stateOffset, s, n))
                    //被强行终止了,因为在全部到达时,其它线程无法修改state的值,因为:
                    //执行doRegister会等待,执行arrive会失败
                    return (int)(state >>> PHASE_SHIFT); // terminated
                releaseWaiters(phase);//释放上个阶段等待的线程
                return nextPhase;
            }
        }
    }

    //当进入phase+1阶段时,会释放phase阶段的线程
    private void releaseWaiters(int phase) {
        QNode q;   // first element of queue
        Thread t;  // its thread
        //根据奇偶标识选择队列
        AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
        while ((q = head.get()) != null &&
               //队列中节点的phase与当前state的阶段数不一致才允许释放线程
               q.phase != (int)(root.state >>> PHASE_SHIFT)) {
            if (head.compareAndSet(q, q.next) &&
                (t = q.thread) != null) {
                q.thread = null;
                LockSupport.unpark(t);
            }
        }
    }
    
    //等待直到当前阶段数不等于phase为止
    //总是顶层实例调用的
    //node一般是null但对于带超时的awaitAdvanceInterruptibly方法需要手动构建node传入
    //由于手动传入了node这样node == null是false,也就不会执行初始自旋了
    private int internalAwaitAdvance(int phase, QNode node) {
        // assert root == this;
        //帮助释放上一个阶段的队列未释放的线程
        releaseWaiters(phase-1);          // ensure old queue clean
        boolean queued = false;           // true when node is enqueued
        int lastUnarrived = 0;            // to increase spins upon change
        int spins = SPINS_PER_ARRIVAL;
        long s;
        int p;
        //检查当前root实例的阶段是否变化,如果变化了说明进入下一个阶段了,这时候就没有必要自旋了
        while ((p = (int)((s = state) >>> PHASE_SHIFT)) == phase) {
            if (node == null) {           // spinning in noninterruptible mode
                int unarrived = (int)s & UNARRIVED_MASK;
                //当前state的unarrived有变化,增加自旋次数
                if (unarrived != lastUnarrived &&
                    (lastUnarrived = unarrived) < NCPU)
                    spins += SPINS_PER_ARRIVAL;
                boolean interrupted = Thread.interrupted();//当前线程是否被中断
                // 中断或自旋完毕,新建一个节点,准备插入到等待队列
                if (interrupted || --spins < 0) { // need node to record intr
                    node = new QNode(this, phase, false, false, 0L);//(Phaser phaser, int phase, boolean interruptible, boolean timed, long nanos)
                    node.wasInterrupted = interrupted;//是否已被中断
                }
            }
            //检查是否可以释放,可以的情况:
            //取消、阶段数发生变化,中断(必须是可中断模式),等待超时
            else if (node.isReleasable()) // done or aborted
                break;
            //自旋无果,准备入队
            else if (!queued) {           // push onto queue
                //为了效率准备了两个队列,这样一旦阶段数发生变化,唤醒旧的线程和新入队的线程不在
                //同一个队列中
                AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
                QNode q = node.next = head.get();
                if ((q == null || q.phase == phase) &&
                    (int)(state >>> PHASE_SHIFT) == phase) // avoid stale enq
                    queued = head.compareAndSet(q, node);
            }
            else {
                try {//已经入队挂起线程
                    //真正的挂起操作是调用node.block()方法,node本身保存了超时时间
                    //知道挂起的等待时间
                    ForkJoinPool.managedBlock(node);
                } catch (InterruptedException ie) {
                    //如果线程被中断那么可以在上面node.isReleasable()分支中退出循环
                    node.wasInterrupted = true;
                }
            }
        }
        //从自旋退出,或被唤醒退出
        if (node != null) {
            if (node.thread != null)
                node.thread = null;       // avoid need for unpark()
            if (node.wasInterrupted && !node.interruptible)
                //如果处在非中断模式,且当前线程已经中断过,那么设置中断标识
                Thread.currentThread().interrupt();
            if (p == phase && (p = (int)(state >>> PHASE_SHIFT)) == phase)
                //这种情况是由于非阶段数改变但退出while(如等待超时(awaitAdvanceInterruptibly超时方法)或中断)
                //执行清理
                return abortWait(phase); // possibly clean up on abort
        }
        releaseWaiters(phase);
        return p;
    }
    
    private int abortWait(int phase) {
        AtomicReference<QNode> head = (phase & 1) == 0 ? evenQ : oddQ;
        for (;;) {
            Thread t;
            QNode q = head.get();
            int p = (int)(root.state >>> PHASE_SHIFT);
            if (q == null || ((t = q.thread) != null && q.phase == p))
                return p;
            //这里总是尝试清理头不位置的结点,而不是一次全部清理
            if (head.compareAndSet(q, q.next) && t != null) {
                q.thread = null;
                LockSupport.unpark(t);
            }
        }
    }

    //挂起当前线程,指定阶段phase全部到达(在执行onAdvance之后)
    public int awaitAdvance(int phase) {
        final Phaser root = this.root;
        long s = (root == this) ? state : reconcileState();
        int p = (int)(s >>> PHASE_SHIFT);
        if (phase < 0)
            return phase;
        if (p == phase)
            //将当前线程放到root的等待队列中,直到phase阶段全部到达
            return root.internalAwaitAdvance(phase, null);
        return p;
    }

    //同awaitAdvance,支持响应中断
    public int awaitAdvanceInterruptibly(int phase)
        throws InterruptedException {
        final Phaser root = this.root;
        long s = (root == this) ? state : reconcileState();
        int p = (int)(s >>> PHASE_SHIFT);
        if (phase < 0)
            return phase;
        if (p == phase) {
            QNode node = new QNode(this, phase, true, false, 0L);//true代表可中断的
            //这里创建一个node传入,可以直接往等待队列插,而无需先自旋一定次数
            p = root.internalAwaitAdvance(phase, node);
            if (node.wasInterrupted)
                throw new InterruptedException();
        }
        return p;
    }

    //同awaitAdvance,支持超时时间
    public int awaitAdvanceInterruptibly(int phase,
                                         long timeout, TimeUnit unit)
        throws InterruptedException, TimeoutException {
        long nanos = unit.toNanos(timeout);
        final Phaser root = this.root;
        long s = (root == this) ? state : reconcileState();
        int p = (int)(s >>> PHASE_SHIFT);
        if (phase < 0)
            return phase;
        if (p == phase) {
            //第一个true代表支持可中断的
            //第二个true代表支持可超时的
            QNode node = new QNode(this, phase, true, true, nanos);
            p = root.internalAwaitAdvance(phase, node);
            if (node.wasInterrupted)//如果是中断返回抛中断异常
                throw new InterruptedException();
            else if (p == phase)//如果是超时,抛超时异常
                throw new TimeoutException();
        }
        return p;
    }

    //强制终止(将state高位设为1,成为负数)
    public void forceTermination() {
        // Only need to change root state
        final Phaser root = this.root;
        long s;
        while ((s = root.state) >= 0) {
            if (UNSAFE.compareAndSwapLong(root, stateOffset,
                                          s, s | TERMINATION_BIT)) {
                // signal all threads
                //释放所有队列的所有线程
                releaseWaiters(0); // Waiters on evenQ
                releaseWaiters(1); // Waiters on oddQ
                return;
            }
        }
    }


    public final int getPhase() {
        return (int)(root.state >>> PHASE_SHIFT);
    }


    public int getRegisteredParties() {
        return partiesOf(state);
    }


    public int getArrivedParties() {
        return arrivedOf(reconcileState());
    }


    public int getUnarrivedParties() {
        return unarrivedOf(reconcileState());
    }


    public Phaser getParent() {
        return parent;
    }


    public Phaser getRoot() {
        return root;
    }

    //是否已终止
    public boolean isTerminated() {
        return root.state < 0L;
    }

    //栅栏方法,当返回true是会终止phaser,这里默认是参与数为0是终止
    protected boolean onAdvance(int phase, int registeredParties) {
        return registeredParties == 0;
    }


    public String toString() {
        return stateToString(reconcileState());
    }


    private String stateToString(long s) {
        return super.toString() +
            "[phase = " + phaseOf(s) +
            " parties = " + partiesOf(s) +
            " arrived = " + arrivedOf(s) + "]";
    }


    /** The number of CPUs, for spin control */
    private static final int NCPU = Runtime.getRuntime().availableProcessors();


    static final int SPINS_PER_ARRIVAL = (NCPU < 2) ? 1 : 1 << 8;
    
    

    static final class QNode implements ForkJoinPool.ManagedBlocker {
        //保存phaser实例,用于判断最初的phase数与实例当前state的phase数是否一致
        //在isReleasable中调用
        final Phaser phaser;
        final int phase;//节点入队时刻的阶段数
        final boolean interruptible;//是否是可中断模式(awaitAdvanceInterruptibly)
        final boolean timed;//是否支持超时(awaitAdvanceInterruptibly)
        boolean wasInterrupted;//线程是否已被中断过
        long nanos;
        final long deadline;
        volatile Thread thread; //指向等待的线程,为null说明执行了取消
        QNode next;

        QNode(Phaser phaser, int phase, boolean interruptible,
              boolean timed, long nanos) {
            this.phaser = phaser;
            this.phase = phase;
            this.interruptible = interruptible;
            this.nanos = nanos;
            this.timed = timed;
            this.deadline = timed ? System.nanoTime() + nanos : 0L;
            thread = Thread.currentThread();
        }

        //当一个线程在入队前自旋过程中判断是否可以退出自旋
        public boolean isReleasable() {
            if (thread == null)//执行了删除
                return true;
            if (phaser.getPhase() != phase) {//阶段数升级了
                thread = null;
                return true;
            }
            if (Thread.interrupted())//线程被中断
                wasInterrupted = true;
            if (wasInterrupted && interruptible) {//如果是可中断模式,也是可以返回的
                thread = null;
                return true;
            }
            if (timed) {
                if (nanos > 0L) {
                    nanos = deadline - System.nanoTime();
                }
                if (nanos <= 0L) {//已经超时
                    thread = null;
                    return true;
                }
            }
            return false;
        }

        //尝试挂起线程
        public boolean block() {
            if (isReleasable())
                return true;
            else if (!timed)
                LockSupport.park(this);
            else if (nanos > 0L)
                LockSupport.parkNanos(this, nanos);
            return isReleasable();
        }
    }

    // Unsafe mechanics

    private static final sun.misc.Unsafe UNSAFE;
    private static final long stateOffset;
    static {
        try {
            UNSAFE = sun.misc.Unsafe.getUnsafe();
            Class<?> k = Phaser.class;
            stateOffset = UNSAFE.objectFieldOffset
                (k.getDeclaredField("state"));
        } catch (Exception e) {
            throw new Error(e);
        }
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值