Java8 ForkJoinPool(一) 源码解析

目录

一、ForkJoinWorkerThread

1、定义

2、run / getPoolIndex

二、InnocuousForkJoinWorkerThread

三、ForkJoinWorkerThreadFactory

四、WorkQueue

1、定义

2、push / pop / poll / pollAt / peek / tryUnpush

3、runTask

4、tryRemoveAndExec

5、popCC / pollAndExecCC

五、ManagedBlocker


      本篇博客重点讲解ForkJoinPool依赖的几个基础类。

一、ForkJoinWorkerThread

1、定义

     ForkJoinWorkerThread继承自Thread,重点改写了其run方法实现,该类包含的实例属性如下:

//负责管理该线程的线程池实现
final ForkJoinPool pool;                // the pool this thread works in

//保存待执行任务的任务队列    
final ForkJoinPool.WorkQueue workQueue; // work-stealing mechanics

   除此之外,还多个表示属性偏移量的静态属性,通过static代码块初始化,如下:

Java8 ForkJoinPool(一) 源码解析_第1张图片

该类的构造方法如下:

 protected ForkJoinWorkerThread(ForkJoinPool pool) {
        //指定初始线程名,registerWorker方法中会修改线程名
        super("aForkJoinWorkerThread");
        this.pool = pool;
        //将当前线程注册到Pool,注册完成后返回WorkQueue实例
        this.workQueue = pool.registerWorker(this);
    }

   
ForkJoinWorkerThread(ForkJoinPool pool, ThreadGroup threadGroup,
                         AccessControlContext acc) {
        //指定初始线程名和ThreadGroup,registerWorker方法中会修改线程名
        super(threadGroup, null, "aForkJoinWorkerThread");
        //修改属性inheritedAccessControlContext
        U.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, acc);
        //清空本地线程变量
        eraseThreadLocals(); // clear before registering
        this.pool = pool;
        //将当前线程注册到Pool,注册完成后返回WorkQueue实例
        this.workQueue = pool.registerWorker(this);
    }

final void eraseThreadLocals() {
        //将保存本地线程变量的两个Map置为null,即清空可能残留的本地线程变量
        U.putObject(this, THREADLOCALS, null);
        U.putObject(this, INHERITABLETHREADLOCALS, null);
    }

 第一种是给DefaultForkJoinWorkerThreadFactory创建新线程使用,第二种是给子类InnocuousForkJoinWorkerThread使用。

2、run / getPoolIndex

     ThreadPoolExecutor中的Worker是实现了Runnable接口,将Worker实例传入Thread的构造方法中执行run方法的,ForkJoinWorkerThread是继承Thread,直接改写其run方法,其实现如下:

//返回当前线程在线程池中的编号
public int getPoolIndex() {
        //注意workQueue是registerWorker后返回的,与线程是1对1的关系
        return workQueue.getPoolIndex();
    }


public void run() {
        if (workQueue.array == null) { // only run once
            Throwable exception = null;
            try {
                //启动前的回调方法,默认空实现
                onStart();
                //启动该线程,从任务队列中获取任务并执行
                pool.runWorker(workQueue);
            } catch (Throwable ex) {
                exception = ex;
            } finally {
                try {
                    //线程退出时的回调方法
                    onTermination(exception);
                } catch (Throwable ex) {
                    if (exception == null)
                        exception = ex;
                } finally {
                    //通知线程池当前线程退出
                    pool.deregisterWorker(this, exception);
                }
            }
        }
    }

protected void onStart() {
    }

protected void onTermination(Throwable exception) {
    }

二、InnocuousForkJoinWorkerThread

       InnocuousForkJoinWorkerThread是ForkJoinWorkerThread的一个内部类,继承自ForkJoinWorkerThread,表示一个特殊的无任何访问权限的线程,不属于任何用户定义的线程组,当执行afterTopLevelExec后会将原线程的本地变量都清空,该类的定义如下:

static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread {
        /** 创建一个全局的线程组 */
        private static final ThreadGroup innocuousThreadGroup =
            createThreadGroup();

        /** An AccessControlContext supporting no privileges */
        private static final AccessControlContext INNOCUOUS_ACC =
            new AccessControlContext(
                new ProtectionDomain[] {
                    //无任务访问权限
                    new ProtectionDomain(null, null)
                });

        InnocuousForkJoinWorkerThread(ForkJoinPool pool) {
            //此构造方法会清空本地线程变量
            super(pool, innocuousThreadGroup, INNOCUOUS_ACC);
        }

        @Override // to erase ThreadLocals
        void afterTopLevelExec() {
            //清空本地线程变量
            eraseThreadLocals();
        }

        @Override // to always report system loader
        public ClassLoader getContextClassLoader() {
            //默认是返回父线程的contextClassLoader,此处改写直接返回SystemClassLoader
            return ClassLoader.getSystemClassLoader();
        }

        @Override //无法设置该线程的异常处理器,即默认为null,出现异常后线程自动退出
        public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { }

        @Override // 不支持设置ClassLoader,直接抛出异常
        public void setContextClassLoader(ClassLoader cl) {
            throw new SecurityException("setContextClassLoader");
        }
        
        //Java中ThreadGroup只提供关联线程的管理维护功能,跟底层的Linux线程组无关联
        private static ThreadGroup createThreadGroup() {
            try {
                sun.misc.Unsafe u = sun.misc.Unsafe.getUnsafe();
                Class tk = Thread.class;
                Class gk = ThreadGroup.class;
                long tg = u.objectFieldOffset(tk.getDeclaredField("group"));
                long gp = u.objectFieldOffset(gk.getDeclaredField("parent"));
                //获取当前线程的线程组
                ThreadGroup group = (ThreadGroup)
                    u.getObject(Thread.currentThread(), tg);
                while (group != null) {
                    //获取父线程组
                    ThreadGroup parent = (ThreadGroup)u.getObject(group, gp);
                    if (parent == null)
                        //找到了最初的祖先级的线程组,使用该线程组创建一个新的线程组
                        return new ThreadGroup(group,
                                               "InnocuousForkJoinWorkerThreadGroup");
                    group = parent;
                }
            } catch (Exception e) {
                throw new Error(e);
            }
            //正常不会进入此代码,直接抛出异常
            throw new Error("Cannot create ThreadGroup");
        }
    }

三、ForkJoinWorkerThreadFactory

       ForkJoinWorkerThreadFactory是ForkJoinPool内部的一个public接口类,用于创建ForkJoinWorkerThread,该接口有两个对应的实现类DefaultForkJoinWorkerThreadFactory和InnocuousForkJoinWorkerThreadFactory,分别用于创建普通的ForkJoinWorkerThread和特殊的InnocuousForkJoinWorkerThread,其实现如下:

public static interface ForkJoinWorkerThreadFactory {
       
        public ForkJoinWorkerThread newThread(ForkJoinPool pool);
    }

static final class DefaultForkJoinWorkerThreadFactory
        implements ForkJoinWorkerThreadFactory {

        public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
            return new ForkJoinWorkerThread(pool);
        }
    }

static final class InnocuousForkJoinWorkerThreadFactory
        implements ForkJoinWorkerThreadFactory {

        /**
         * An ACC to restrict permissions for the factory itself.
         * The constructed workers have no permissions set.
         */
        private static final AccessControlContext innocuousAcc;
        static {
            Permissions innocuousPerms = new Permissions();
            //对应的RuntimePermission为modifyThread
            innocuousPerms.add(modifyThreadPermission);
            //允许改写获取ContextClassLoader的方法
            innocuousPerms.add(new RuntimePermission(
                                   "enableContextClassLoaderOverride"));
            //允许修改ThreadGroup
            innocuousPerms.add(new RuntimePermission(
                                   "modifyThreadGroup"));

            innocuousAcc = new AccessControlContext(new ProtectionDomain[] {
                    new ProtectionDomain(null, innocuousPerms)
                });
        }

        public final ForkJoinWorkerThread newThread(ForkJoinPool pool) {
            return (ForkJoinWorkerThread.InnocuousForkJoinWorkerThread)
                java.security.AccessController.doPrivileged(
                    new java.security.PrivilegedAction() {
                    public ForkJoinWorkerThread run() {
                        return new ForkJoinWorkerThread.
                            InnocuousForkJoinWorkerThread(pool);
                    }}, innocuousAcc);
        }
    }

四、WorkQueue

1、定义

     WorkQueue是ForkJoinPool的内部类,用来保存待执行的任务的队列,该类没有实现队列接口,完全是ForkJoinPool定制的,其访问权限是包级访问权限。该类包含的实例属性如下:

        //当前队列的状态,如果小于0表示未激活,大于0表示已激活
        //如果最后一位是1,即是奇数,则表示关联的Worker线程正在扫描获取待执行的任务,最后一位是0,即偶数,表示关联的Worker线程正在执行任务
        //scanState是会变化的,每次改变时是在当前ctl的基础上加上SS_SEQ
        volatile int scanState;    // versioned, <0: inactive; odd:scanning
        
        //当前WorkQueue被标记成未激活状态时ctl属性的低32位的值,其中低16位保存在此之间被标记为未激活状态的WorkQueue在数组中的索引
        int stackPred;             // pool stack (ctl) predecessor
        
        //表示当前队列从其他队列中偷过来并执行的任务数
        int nsteals;               // number of steals
        
        //hint是在WorkerQueue创建时初始化的,初始值为当前线程的Probe
        //当从其他WorkerQueue获取未执行的任务时,用来临时保存被偷取任务的WorkerQueue的索引
        int hint;                  // randomization and stealer index hint
   
        //高16位保存队列的类型,是先进先出还是后进先出,取决于线程池的配置,如果小于0表示该队列是共享的
        //低16位保存当前队列在队列数组中的位置
        int config;                // pool index and mode

        //1表示已加锁,负值表示当前队列已终止,不能接受新的任务,Worker退出或者线程池终止时会将qlock属性置为-1
        //正常是0
        volatile int qlock;        // 1: locked, < 0: terminate; else 0
        
        //下一次poll时对应的数组索引
        volatile int base;         // index of next slot for poll
        
        //下一次push时对应的数组索引
        int top;                   // index of next slot for push

        //实际保存ForkJoinTask的数组
        ForkJoinTask[] array;   // the elements (initially unallocated)

        //关联的线程池
        final ForkJoinPool pool;   // the containing pool (may be null)

        //拥有此队列的ForkJoinWorkerThread 
        final ForkJoinWorkerThread owner; // owning thread or null if shared
        
        //如果队列长期为空则会被置为未激活状态,关联的Worker线程也会休眠,parker属性就是记录关联的Worker线程,跟上面的owner是一样的
        volatile Thread parker;    // == owner during call to park; else null
        
        //必须等待currentJoin执行完成而让当前线程阻塞
        volatile ForkJoinTask currentJoin;  // task being joined in awaitJoin
        
        //当前线程通过scan方法获取待执行的任务,该任务可能是当前队列的,也可能是其他某个队列的
        volatile ForkJoinTask currentSteal; // mainly used by helpStealer

该类包含的静态属性通过static代码块初始化,表示某个属性的偏移量,如下:

Java8 ForkJoinPool(一) 源码解析_第2张图片

除此之外,还有两个静态常量,如下:

//初始队列容量
static final int INITIAL_QUEUE_CAPACITY = 1 << 13;

//最大队列容量
static final int MAXIMUM_QUEUE_CAPACITY = 1 << 26; // 64M

 该类的构造方法如下:

Java8 ForkJoinPool(一) 源码解析_第3张图片

注意base和top的初始值都不是0,而是初始值的一半,即从数组的中间开始插入新元素或者移除元素。 

2、push / pop / poll / pollAt / peek / tryUnpush

//插入一个新任务
final void push(ForkJoinTask task) {
            ForkJoinTask[] a; ForkJoinPool p;
            int b = base, s = top, n;
            //执行runWorker方法时会通过growArray方法初始化array
            //一旦关联的ForkJoinWorkerThread解除注册了则会将其置为null
            if ((a = array) != null) {    //如果队列被移除了则忽略
                int m = a.length - 1;
                //将task保存到数组中,m & s的结果就是新元素在数组中的位置,如果s大于m则求且的结果是0,又从0逐步增长到索引最大值  
                U.putOrderedObject(a, ((m & s) << ASHIFT) + ABASE, task);
                //修改top属性,加1,注意top属性会一直加1
                U.putOrderedInt(this, QTOP, s + 1);
                if ((n = s - b) <= 1) { //如果原来数组是空的
                    if ((p = pool) != null)
                        //唤醒因为待执行任务为空而阻塞的线程
                        p.signalWork(p.workQueues, this);
                }
                else if (n >= m) //说明数组满了
                    growArray();
            }
        }

//数组扩容,会将原老数组的元素复制到新数组中,老数组中对应的位置置为null
final ForkJoinTask[] growArray() {
            ForkJoinTask[] oldA = array;
            //获取扩容后的容量,如果array未初始化则是INITIAL_QUEUE_CAPACITY
            int size = oldA != null ? oldA.length << 1 : INITIAL_QUEUE_CAPACITY;
            if (size > MAXIMUM_QUEUE_CAPACITY)
                throw new RejectedExecutionException("Queue capacity exceeded");
            int oldMask, t, b;
            //创建一个新数组
            ForkJoinTask[] a = array = new ForkJoinTask[size];
            if (oldA != null && (oldMask = oldA.length - 1) >= 0 &&
                (t = top) - (b = base) > 0) { //老数组中还有未被移除的元素
                int mask = size - 1;
                do { //从base往top遍历,将老数组中的元素拷贝到新数组中,老数组对应位置的数组元素置为null
                    ForkJoinTask x;
                    int oldj = ((b & oldMask) << ASHIFT) + ABASE;
                    int j    = ((b &    mask) << ASHIFT) + ABASE;
                    //获取原数组oldj处的元素
                    x = (ForkJoinTask)U.getObjectVolatile(oldA, oldj);
                    if (x != null &&
                        U.compareAndSwapObject(oldA, oldj, x, null))//将老数组oldj处的元素置为null,将x保存到新数组的j处
                        U.putObjectVolatile(a, j, x);
                } while (++b != t);
            }
            return a;
        }

//弹出上一次push的元素
final ForkJoinTask pop() {
            ForkJoinTask[] a; ForkJoinTask t; int m;
            if ((a = array) != null && (m = a.length - 1) >= 0) {
                for (int s; (s = top - 1) - base >= 0;) { //有未移除的元素
                    //获取上一次push的元素在数组中的索引
                    long j = ((m & s) << ASHIFT) + ABASE;
                    //如果该索引的元素为null,则终止循环
                    if ((t = (ForkJoinTask)U.getObject(a, j)) == null)
                        break; 
                    //将j处的元素置为null,修改top属性,返回j处的元素    
                    if (U.compareAndSwapObject(a, j, t, null)) {
                        U.putOrderedInt(this, QTOP, s);
                        return t;
                    }
                }
            }
            //数组未初始化或者数组为空
            return null;
        }

//获取并移除base对应的数组元素
final ForkJoinTask poll() {
            ForkJoinTask[] a; int b; ForkJoinTask t;
            //数组不为空且还有未移除的元素
            while ((b = base) - top < 0 && (a = array) != null) {
                //获取base对应数组索引处的元素
                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                t = (ForkJoinTask)U.getObjectVolatile(a, j);
                if (base == b) { //如果base未发生改变
                    if (t != null) {
                        //通过cas将其置为null,base加1,返回该元素
                        if (U.compareAndSwapObject(a, j, t, null)) {
                            base = b + 1;
                            return t;
                        }
                    }
                    else if (b + 1 == top) // now empty
                        break;
                }//如果base发生改变则下一次while循环重新读取base
            }
            return null;
        }

//获取指定数组索引的元素,要求b等于base,否则返回null
final ForkJoinTask pollAt(int b) {
            ForkJoinTask t; ForkJoinTask[] a;
            if ((a = array) != null) {
                int j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                if ((t = (ForkJoinTask)U.getObjectVolatile(a, j)) != null &&
                    //只有base等于b的时候才会将对应的数组元素置为null并返回该元素
                    base == b && U.compareAndSwapObject(a, j, t, null)) {
                    base = b + 1;
                    return t;
                }
            }
            return null;
        }

final ForkJoinTask peek() {
            ForkJoinTask[] a = array; int m;
            //如果数组未初始化
            if (a == null || (m = a.length - 1) < 0)
                return null;
            //如果是后进先出则是top - 1 ,如果是先进先出则是base   
            int i = (config & FIFO_QUEUE) == 0 ? top - 1 : base;
            int j = ((i & m) << ASHIFT) + ABASE;
            //获取队列头或者队列尾的元素,取决于队列的类型
            return (ForkJoinTask)U.getObjectVolatile(a, j);
        }

//如果t是上一次push的元素,则将top减1,对应的数组元素置为null,返回true
final boolean tryUnpush(ForkJoinTask t) {
            ForkJoinTask[] a; int s;
            if ((a = array) != null && (s = top) != base &&
                U.compareAndSwapObject
                //如果t是上一次push插入的元素,则将其置为null,同时修改s
                (a, (((a.length - 1) & --s) << ASHIFT) + ABASE, t, null)) {
                U.putOrderedInt(this, QTOP, s);
                return true;
            }
            return false;
        }

3、runTask

       runTask方法会执行指定的任务,并且将任务数组中包含的所有未处理任务都执行完成,注意指定的任务不一定是当前WorkQueue中包含的,有可能是从其他WorkQueue中偷过来的。

//执行特定任务,并执行完当前数组中包含的所有未处理任务
final void runTask(ForkJoinTask task) {
            if (task != null) {
                 //SCANNING的值就是1,将最后一位置为0,表示正在执行任务
                scanState &= ~SCANNING; // mark as busy
                //执行task
                (currentSteal = task).doExec();
                //将currentSteal属性置为null
                U.putOrderedObject(this, QCURRENTSTEAL, null); // release for GC
                //执行当前数组中包含的未处理的任务
                execLocalTasks();
                ForkJoinWorkerThread thread = owner;
                if (++nsteals < 0)      
                //nsteals已经超过最大值了,变成负值了,则将其累加到ForkJoinPool的stealCounter属性中
                //并重置为0
                    transferStealCount(pool);
                //重新打标成SCANNING
                scanState |= SCANNING;
                if (thread != null)
                    //执行回调方法
                    thread.afterTopLevelExec();
            }
        }

 final void execLocalTasks() {
            int b = base, m, s;
            ForkJoinTask[] a = array;
            //如果数组已经初始化且包含未处理的元素
            if (b - (s = top - 1) <= 0 && a != null &&
                (m = a.length - 1) >= 0) {
                if ((config & FIFO_QUEUE) == 0) {
                    //如果是后进先出队列,从top开始往前遍历直到base
                    for (ForkJoinTask t;;) {
                         //获取s对应的数组元素
                        if ((t = (ForkJoinTask)U.getAndSetObject
                             (a, ((m & s) << ASHIFT) + ABASE, null)) == null)
                            break;
                        //修改top    
                        U.putOrderedInt(this, QTOP, s);
                        t.doExec(); //执行任务
                        if (base - (s = top - 1) > 0) //所有元素都遍历完了
                            break;
                    }
                }
                else
                    //如果是先进先出
                    pollAndExecAll();
            }
        }

final void pollAndExecAll() {
            for (ForkJoinTask t; (t = poll()) != null;)
                t.doExec();
        }

final void transferStealCount(ForkJoinPool p) {
            AtomicLong sc;
            if (p != null && (sc = p.stealCounter) != null) {
                int s = nsteals;
                //恢复成0
                nsteals = 0;            // if negative, correct for overflow
                //累加到ForkJoinPool的stealCounter属性中
                sc.getAndAdd((long)(s < 0 ? Integer.MAX_VALUE : s));
            }
        }

4、tryRemoveAndExec


//如果队列为空且不知道task的状态,则返回true
//如果找到目标task,会将其从数组中移除并执行
//在遍历数组的过程中,如果发现任务被取消了,则会将其从数组中丢弃
final boolean tryRemoveAndExec(ForkJoinTask task) {
            ForkJoinTask[] a; int m, s, b, n;
            if ((a = array) != null && (m = a.length - 1) >= 0 &&
                task != null) { //数组和task非空
                while ((n = (s = top) - (b = base)) > 0) { //还有未处理的任务
                    for (ForkJoinTask t;;) {      // traverse from s to b
                        //s先减1再求且
                        long j = ((--s & m) << ASHIFT) + ABASE;
                        //如果索引为j的数组元素为null
                        if ((t = (ForkJoinTask)U.getObject(a, j)) == null)
                            return s + 1 == top;     //如果为true,说明数组是空的
                        else if (t == task) {
                            //找到了匹配的任务
                            boolean removed = false;
                            if (s + 1 == top) {      //目标task就是上一次push的元素
                                if (U.compareAndSwapObject(a, j, task, null)) {
                                    //将对应的数组元素置为null,然后修改top属性
                                    U.putOrderedInt(this, QTOP, s);
                                    removed = true;
                                }
                            }
                            //s+1不等于top,即目标task位于中间的位置,将用一个空的EmptyTask代替
                            else if (base == b)      // replace with proxy
                                removed = U.compareAndSwapObject(
                                    a, j, task, new EmptyTask());
                            if (removed)
                                 //如果成功移除该task,则执行该任务
                                task.doExec();
                            break; //终止内存for循环,通过外层的while循环,重启for循环
                        }
                        //t不等于task
                        //如果t被取消了,且t位于栈顶
                        else if (t.status < 0 && s + 1 == top) {
                            if (U.compareAndSwapObject(a, j, t, null))
                                U.putOrderedInt(this, QTOP, s); //修改top属性,即将被取消掉的任务给丢弃掉
                            break;                  // was cancelled
                        }
                        //先减n减1,再判断n是否为0,如果为0,说明数组中所有元素都遍历完了,返回false
                        if (--n == 0)
                            return false;
                    }//for循环结束
                    if (task.status < 0) //task被取消了,返回false
                        return false;
                }//while循环结束
            }
            return true;
        }

5、popCC / pollAndExecCC

//如果栈顶的元素是CountedCompleter,则以该元素为起点向上遍历他的父节点,直到找到目标task元素,将栈顶的
//CountedCompleter从数组中移除并返回,top减1
final CountedCompleter popCC(CountedCompleter task, int mode) {
            int s; ForkJoinTask[] a; Object o;
            if (base - (s = top) < 0 && (a = array) != null) {
                //如果数组非空
                long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
                if ((o = U.getObjectVolatile(a, j)) != null &&
                    (o instanceof CountedCompleter)) {
                    //如果栈顶的任务是CountedCompleter
                    CountedCompleter t = (CountedCompleter)o;
                    for (CountedCompleter r = t;;) {
                        if (r == task) {//如果找到目标task
                            if (mode < 0) { //该队列是共享的,会被多个线程修改,必须加锁
                                if (U.compareAndSwapInt(this, QLOCK, 0, 1)) { //加锁
                                    if (top == s && array == a &&  //如果top属性和array属性都未改变,将索引为j的元素置为null
                                        U.compareAndSwapObject(a, j, t, null)) {
                                        U.putOrderedInt(this, QTOP, s - 1); //top减1
                                        U.putOrderedInt(this, QLOCK, 0); //释放锁
                                        return t;
                                    }
                                    //上述if不成立,解锁
                                    U.compareAndSwapInt(this, QLOCK, 1, 0);
                                }
                            }
                            //mode大于等于0,是某个Worker线程独享的,不需要加锁
                            else if (U.compareAndSwapObject(a, j, t, null)) { //将索引为j的元素置为null
                                U.putOrderedInt(this, QTOP, s - 1);
                                return t;
                            }
                            break;
                        }
                        else if ((r = r.completer) == null) //遍历父节点,如果为null说明都遍历完了
                            break;
                    }
                }
            }
            return null;
        }

//如果base对应的数组元素是CountedCompleter,则以该节点作为起点,往上遍历其父节点,如果找到目标节点task,则执行并返回1        
final int pollAndExecCC(CountedCompleter task) {
            int b, h; ForkJoinTask[] a; Object o;
            if ((b = base) - top >= 0 || (a = array) == null) //如果数组为空
                h = b | Integer.MIN_VALUE;  // to sense movement on re-poll
            else {
                //如果数组不为空,获取base对应的元素
                long j = (((a.length - 1) & b) << ASHIFT) + ABASE;
                if ((o = U.getObjectVolatile(a, j)) == null)//如果base对应的元素为null,返回2
                    h = 2;                  // retryable
                else if (!(o instanceof CountedCompleter)) //如果base对应的元素不是CountedCompleter,返回-1
                    h = -1;                 // unmatchable
                else {
                    //base对应的元素是CountedCompleter
                    CountedCompleter t = (CountedCompleter)o;
                    for (CountedCompleter r = t;;) {
                        if (r == task) {
                            //匹配到目标元素
                            if (base == b &&
                                U.compareAndSwapObject(a, j, t, null)) {
                                //base未改变且成功将j对应的数组元素置为null,将base加1,并执行该任务,返回1
                                base = b + 1;
                                t.doExec();
                                h = 1;      // success
                            }
                            else
                                //base变了或者cas失败,返回2
                                h = 2;      // lost CAS
                            break;
                        }
                        else if ((r = r.completer) == null) { //往上遍历父节点,如果为null,则返回-1
                            h = -1;         // unmatched
                            break;
                        }
                    }
                }
            }
            return h;
        }

五、ManagedBlocker

    ManagedBlocker接口的定义比较简单,如下:

Java8 ForkJoinPool(一) 源码解析_第4张图片

其中block方法用于将当前线程阻塞,isReleasable方法返回true表示不需要阻塞了,该接口的典型实现就是Phaser的内部类QNode,可以参考《Java8 Phaser 源码解析》 。

    ManagedBlocker接口通常跟ForkJoinPool的静态方法managedBlock配合使用,该方法的实现如下:

public static void managedBlock(ManagedBlocker blocker)
        throws InterruptedException {
        ForkJoinPool p;
        ForkJoinWorkerThread wt;
        Thread t = Thread.currentThread();
        if ((t instanceof ForkJoinWorkerThread) && //如果是ForkJoinWorkerThread
            (p = (wt = (ForkJoinWorkerThread)t).pool) != null) {
            WorkQueue w = wt.workQueue;
            while (!blocker.isReleasable()) { //如果需要阻塞
                if (p.tryCompensate(w)) { //进一步判断是否需要阻塞
                    try {
                        //让当前线程阻塞
                        do {} while (!blocker.isReleasable() &&
                                     !blocker.block());
                    } finally {
                        //活跃的线程数加1
                        U.getAndAddLong(p, CTL, AC_UNIT);
                    }
                    break;
                }
            }
        }
        else {
            //普通的JavaThread
            do {} while (!blocker.isReleasable() &&
                         !blocker.block());
        }
    }

 

你可能感兴趣的:(java8并发工具类源码解析)