Java8 ForkJoinPool(二) 源码解析

目录

        1、定义

2、构造方法

3、invoke / execute / submit / invokeAll

4、externalPush / tryExternalUnpush

5、lockRunState / unlockRunState


       本篇博客重点讲解ForkJoinPool的定义及其提交任务到线程池的实现。

1、定义

     ForkJoinPool的类继承关系如下:

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

该类包含的属性如下:

   //最高的16位表示获取线程数,第二个16位表示总的线程数
   //如果有空闲线程,最低的16位中保存空闲线程关联的WorkQueue在WorkQueue数组中的索引 
   volatile long ctl;                   // main pool control
    
    //描述线程池的状态
    volatile int runState;               // lockable status
    
    //高16位保存线程池的队列模式,FIFO或者LIFO
    //低16位保存线程池的parallelism属性
    final int config;                    // parallelism, mode
    
    //累加SEED_INCREMENT生成的一个随机数,决定新增的Worker对应的WorkQueue在数组中的索引
    int indexSeed;                       // to generate worker index

    //WorkQueue数组
    volatile WorkQueue[] workQueues;     // main registry
    
    //生成Worker线程的工厂类
    final ForkJoinWorkerThreadFactory factory;
    
    //异常处理器
    final UncaughtExceptionHandler ueh;  // per-worker UEH
    
    //生成的Worker线程的线程名前缀
    final String workerNamePrefix;       // to create worker name string
    
    //累计的从其他WorkQueue中偷过来的待执行的任务
    volatile AtomicLong stealCounter;    // also used as sync monitor

 包含的静态属性如下:

    //创建ForkJoinWorkerThread的工厂类
    public static final ForkJoinWorkerThreadFactory
        defaultForkJoinWorkerThreadFactory;

    //线程池关闭时检查当前线程是否有此权限
    private static final RuntimePermission modifyThreadPermission;

    //common线程池
    static final ForkJoinPool common;

    //common线程池的parallelism属性
    static final int commonParallelism;

    //限制最大的线程数,默认值为常量DEFAULT_COMMON_MAX_SPARES,256
    private static int commonMaxSpares;
   
    //生成poolId使用
    private static int poolNumberSequence;

    // Unsafe mechanics
    private static final sun.misc.Unsafe U;
    private static final int  ABASE;
    private static final int  ASHIFT;
    private static final long CTL;
    private static final long RUNSTATE;
    private static final long STEALCOUNTER;
    private static final long PARKBLOCKER;
    private static final long QTOP;
    private static final long QLOCK;
    private static final long QSCANSTATE;
    private static final long QPARKER;
    private static final long QCURRENTSTEAL;
    private static final long QCURRENTJOIN;

    static {
        //获取属性的偏移量
        try {
            U = sun.misc.Unsafe.getUnsafe();
            Class k = ForkJoinPool.class;
            CTL = U.objectFieldOffset
                (k.getDeclaredField("ctl"));
            RUNSTATE = U.objectFieldOffset
                (k.getDeclaredField("runState"));
            STEALCOUNTER = U.objectFieldOffset
                (k.getDeclaredField("stealCounter"));
            Class tk = Thread.class;
            PARKBLOCKER = U.objectFieldOffset
                (tk.getDeclaredField("parkBlocker"));
            Class wk = WorkQueue.class;
            QTOP = U.objectFieldOffset
                (wk.getDeclaredField("top"));
            QLOCK = U.objectFieldOffset
                (wk.getDeclaredField("qlock"));
            QSCANSTATE = U.objectFieldOffset
                (wk.getDeclaredField("scanState"));
            QPARKER = U.objectFieldOffset
                (wk.getDeclaredField("parker"));
            QCURRENTSTEAL = U.objectFieldOffset
                (wk.getDeclaredField("currentSteal"));
            QCURRENTJOIN = U.objectFieldOffset
                (wk.getDeclaredField("currentJoin"));
            Class ak = ForkJoinTask[].class;
            //用于获取ForkJoinTask数组指定索引元素的偏移量
            ABASE = U.arrayBaseOffset(ak);
            int scale = U.arrayIndexScale(ak);
            if ((scale & (scale - 1)) != 0)
                throw new Error("data type scale not a power of two");
            ASHIFT = 31 - Integer.numberOfLeadingZeros(scale);
        } catch (Exception e) {
            throw new Error(e);
        }
        
        //DEFAULT_COMMON_MAX_SPARES的值是256
        commonMaxSpares = DEFAULT_COMMON_MAX_SPARES;
        defaultForkJoinWorkerThreadFactory =
            new DefaultForkJoinWorkerThreadFactory();
        modifyThreadPermission = new RuntimePermission("modifyThread");

        common = java.security.AccessController.doPrivileged
            (new java.security.PrivilegedAction() {
                public ForkJoinPool run() { return makeCommonPool(); }});
        //获取common线程池的parallelism属性        
        int par = common.config & SMASK; // report 1 even if threads disabled
        commonParallelism = par > 0 ? par : 1;
    }

    //创建common线程池
    private static ForkJoinPool makeCommonPool() {
        int parallelism = -1;
        ForkJoinWorkerThreadFactory factory = null;
        UncaughtExceptionHandler handler = null;
        try {  //读取三个属性值
            String pp = System.getProperty
                ("java.util.concurrent.ForkJoinPool.common.parallelism");
            String fp = System.getProperty
                ("java.util.concurrent.ForkJoinPool.common.threadFactory");
            String hp = System.getProperty
                ("java.util.concurrent.ForkJoinPool.common.exceptionHandler");
            //根据属性配置初始化变量   
            if (pp != null)
                parallelism = Integer.parseInt(pp);
            if (fp != null)
                factory = ((ForkJoinWorkerThreadFactory)ClassLoader.
                           getSystemClassLoader().loadClass(fp).newInstance());
            if (hp != null)
                handler = ((UncaughtExceptionHandler)ClassLoader.
                           getSystemClassLoader().loadClass(hp).newInstance());
        } catch (Exception ignore) {
        }
        if (factory == null) {
            if (System.getSecurityManager() == null)
                factory = defaultForkJoinWorkerThreadFactory;
            else // use security-managed default
                factory = new InnocuousForkJoinWorkerThreadFactory();
        }
        if (parallelism < 0 && //如果没有设置属性parallelism,则默认使用CPU核数减1,如果是单核的则为1
            (parallelism = Runtime.getRuntime().availableProcessors() - 1) <= 0)
            parallelism = 1;
        if (parallelism > MAX_CAP) //如果配置的parallelism大于MAX_CAP,则为MAX_CAP,0x7fff,32767
            parallelism = MAX_CAP;
         //注意common线程池的模式是LIFO,后进先出    
        return new ForkJoinPool(parallelism, factory, handler, LIFO_QUEUE,
                                "ForkJoinPool.commonPool-worker-");
    }

 包含的静态常量如下:

    //用于获取保存在config属性低16位中的parallelism属性
    static final int SMASK        = 0xffff;        // short bits == max index
    //parallelism属性的最大值
    static final int MAX_CAP      = 0x7fff;        // max #workers - 1
    //跟SMASK相比,最后一位是0而不是1,用来计算遍历workQueues的步长
    static final int EVENMASK     = 0xfffe;        // even short bits
    //取值是126,二进制表示是1111110,WorkQueue数组元素个数的最大值
    static final int SQMASK       = 0x007e;        // max 64 (even) slots

    //WorkQueue.scanState属性中表示状态的位
    //最低位为1表示关联的Worker线程正在扫描获取待执行的任务,为0表示正在执行任务
    static final int SCANNING     = 1;             // false when running tasks
    //最高位为1表示当前WorkQueue为非激活状态,刚创建时状态就是INACTIVE,可通过signalWork方法将其变成激活状态
    //最高位为0表示当前WorkQueue为激活状态
    static final int INACTIVE     = 1 << 31;       // must be negative
    //一个自增值,ctl属性的低32位加上SS_SEQ,计算一个新的scanState
    static final int SS_SEQ       = 1 << 16;       // version count

    // ForkJoinPool.config 和 WorkQueue.config 属性中,高16位表示队列的模式
    static final int MODE_MASK    = 0xffff << 16;  // top half of int
    static final int LIFO_QUEUE   = 0; //后进先出模式  
    static final int FIFO_QUEUE   = 1 << 16;  //先进先出模式
    static final int SHARED_QUEUE = 1 << 31;       //共享模式

    //Worker线程的空闲时间,单位是纳秒
    private static final long IDLE_TIMEOUT = 2000L * 1000L * 1000L; // 2sec

    //允许的阻塞时间误差
    private static final long TIMEOUT_SLOP = 20L * 1000L * 1000L;  // 20ms

    //commonMaxSpares的初始值,线程池中线程数的最大值
    private static final int DEFAULT_COMMON_MAX_SPARES = 256;

    //自旋等待的次数,设置成0可减少对CPU的占用,且没有对应的方法可以修改SPINS属性
    private static final int SPINS  = 0;

    //生成随机数的种子
    private static final int SEED_INCREMENT = 0x9e3779b9;

    
    //获取低32位的值
    private static final long SP_MASK    = 0xffffffffL;
    //获取高32位的值
    private static final long UC_MASK    = ~SP_MASK;

    //活跃线程数,保存在ctl中的最高16位
    private static final int  AC_SHIFT   = 48;
    private static final long AC_UNIT    = 0x0001L << AC_SHIFT;
    private static final long AC_MASK    = 0xffffL << AC_SHIFT;

    //总的线程数,保存在ctl中的第二个16位
    private static final int  TC_SHIFT   = 32;
    private static final long TC_UNIT    = 0x0001L << TC_SHIFT;
    private static final long TC_MASK    = 0xffffL << TC_SHIFT;
    //如果第48位为1,表示需要新增一个Worker线程
    //第48位对应于TC的最高位,如果为1,说明总的线程数小于parallelism属性,可以新增线程
    private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15); // sign

    //runState属性不同的位表示的含义,描述线程池的状态
    //如果runState小于0,即最高位为1,说明线程池正在关闭的过程中
    //如果runState大于0,说明线程池是正常运行的
    private static final int  RSLOCK     = 1; //表示已加锁
    private static final int  RSIGNAL    = 1 << 1; //表示有线程等待获取锁
    private static final int  STARTED    = 1 << 2; //表示线程已启动
    //表示线程池的状态是STOP,不接受新的任务且会丢弃掉任务队列中未执行的任务
    private static final int  STOP       = 1 << 29;
    //表示线程池已终止
    private static final int  TERMINATED = 1 << 30;
    //表示线程池的状态是SHUTDOWN,不接受新的任务
    private static final int  SHUTDOWN   = 1 << 31; 

2、构造方法

public ForkJoinPool() {
        this(Math.min(MAX_CAP, Runtime.getRuntime().availableProcessors()),
             defaultForkJoinWorkerThreadFactory, null, false);
    }

public ForkJoinPool(int parallelism) {
        this(parallelism, defaultForkJoinWorkerThreadFactory, null, false);
    }

public ForkJoinPool(int parallelism,
                        ForkJoinWorkerThreadFactory factory,
                        UncaughtExceptionHandler handler,
                        boolean asyncMode) {
        this(checkParallelism(parallelism),
             checkFactory(factory),
             handler,
             asyncMode ? FIFO_QUEUE : LIFO_QUEUE,
             "ForkJoinPool-" + nextPoolId() + "-worker-");
        checkPermission();
    }

private static void checkPermission() {
        SecurityManager security = System.getSecurityManager();
        if (security != null)
            security.checkPermission(modifyThreadPermission);
    }

private static int checkParallelism(int parallelism) {
        if (parallelism <= 0 || parallelism > MAX_CAP)
            throw new IllegalArgumentException();
        return parallelism;
    }

private static ForkJoinWorkerThreadFactory checkFactory
        (ForkJoinWorkerThreadFactory factory) {
        if (factory == null)
            throw new NullPointerException();
        return factory;
    }

private static final synchronized int nextPoolId() {
        return ++poolNumberSequence;
    }

private ForkJoinPool(int parallelism,
                         ForkJoinWorkerThreadFactory factory,
                         UncaughtExceptionHandler handler,
                         int mode,
                         String workerNamePrefix) {
        this.workerNamePrefix = workerNamePrefix;
        this.factory = factory;
        this.ueh = handler;
        //parallelism不能超过MAX_CAP,跟SMASK求且的结果不变
        this.config = (parallelism & SMASK) | mode;
        long np = (long)(-parallelism); // offset ctl counts
        //左移48位后取高16位 和 左移32位后取第二个16位
        //以parallelism是3为例,此时ctl是1111111111111101111111111111110100000000000000000000000000000000
        this.ctl = ((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
    }

3、invoke / execute / submit / invokeAll

     invoke方法是ForkJoinPool的特有方法,会将指定任务提交到任务队列中并阻塞当前线程等待任务执行完成;execute,submit,invokeAll方法都是改写了父类AbstractExecutorService的实现,原实现是将Runnable或者Callable接口包装成FutureTask,这里统一包装成ForkJoinTask的某个子类。

public  T invoke(ForkJoinTask task) {
        if (task == null)
            throw new NullPointerException();
        //将新任务加入到任务队列中    
        externalPush(task);
        return task.join(); //等待任务执行完成
    }

public void execute(ForkJoinTask task) {
        if (task == null)
            throw new NullPointerException();
        //将新任务加入到任务队列中     
        externalPush(task);
    }

public void execute(Runnable task) {
        if (task == null)
            throw new NullPointerException();
        ForkJoinTask job;
        if (task instanceof ForkJoinTask) // avoid re-wrap
            job = (ForkJoinTask) task;
        else
            //如果不是ForkJoinTask,则进行一层保证
            job = new ForkJoinTask.RunnableExecuteAction(task);
        //将新任务加入到任务队列中        
        externalPush(job);
    }

public  ForkJoinTask submit(ForkJoinTask task) {
        if (task == null)
            throw new NullPointerException();
        //将新任务加入到任务队列中     
        externalPush(task);
        return task;
    }

public  ForkJoinTask submit(Callable task) {
        //将Callable进行包装
        ForkJoinTask job = new ForkJoinTask.AdaptedCallable(task);
        //将新任务加入到任务队列中 
        externalPush(job);
        return job;
    }

public  ForkJoinTask submit(Runnable task, T result) {
        //将Runnable给包装成ForkJoinTask
        ForkJoinTask job = new ForkJoinTask.AdaptedRunnable(task, result);
        externalPush(job);
        return job;
    }

public ForkJoinTask submit(Runnable task) {
        if (task == null)
            throw new NullPointerException();
        ForkJoinTask job;
        if (task instanceof ForkJoinTask) // avoid re-wrap
            job = (ForkJoinTask) task;
        else
            //将Runnable给包装成ForkJoinTask
            job = new ForkJoinTask.AdaptedRunnableAction(task);
        externalPush(job);
        return job;
    }

 public  List> invokeAll(Collection> tasks) {
        ArrayList> futures = new ArrayList<>(tasks.size());

        boolean done = false;
        try {
            for (Callable t : tasks) {
                //Callable包装成ForkJoinTask
                ForkJoinTask f = new ForkJoinTask.AdaptedCallable(t);
                futures.add(f);
                externalPush(f);
            }
            for (int i = 0, size = futures.size(); i < size; i++)
                ((ForkJoinTask)futures.get(i)).quietlyJoin(); //等待任务执行完成
            done = true;
            return futures;
        } finally {
            if (!done)
                for (int i = 0, size = futures.size(); i < size; i++)
                    futures.get(i).cancel(false); //出现异常取消掉剩余的未执行任务
        }
    }

4、externalPush / tryExternalUnpush

      ForkJoinPool跟ThreadPoolExecutor不同,后者只有一个支持阻塞的任务队列,前者是有多个任务队列,任务队列的数量是大于2*parallelism的最小的2的整数次幂的值,且任务队列是非阻塞的,多个任务队列的设计跟LongAdder的设计思想类似,可减少高并发提交任务时减少对同一个队列的竞争,减少因加锁解锁等同步操作的性能损耗。

     将某个任务提交到任务队列时,是根据m & r & SQMASK的方式来计算所属的任务队列,其中m等于任务队列数组的长度减1,r等于当前线程的probe属性,SQMASK是任务队列数组的最大个数。如果所属的任务队列未初始化,则会创建一个新的任务队列,注意新创建的任务队列是SHARED_QUEUE共享模式,即不属于某个Worker线程,且是INACTIVE状态的。

     如果某个task是位于关联的任务队列的顶端,即是最近一次插入的task,则将其从任务队列中移除,如果成功移除则tryExternalUnpush返回true,否则返回false。

     externalPush方法是invoke / execute / submit / invokeAll等方法的核心实现,将某个任务提交到任务队列中,如果当前线程的probe属性未初始化,则初始化probe属性;如果线程池未初始化则初始化线程池,初始化线程池就是根据parallelism属性初始化WorkQueue数组和stealCounter属性;如果该task关联的WorkQueue未初始化,则创建一个新的WorkQueue,新WorkQueue是SHARED_QUEUE和INACTIVE的,最后将任务添加到这个新的WorkQueue中;如果关联的WorkQueue不为空,则将其添加到关联的WorkQueue中。只要添加到WorkQueue成功,如果没有空闲的Worker线程且当前线程数小于parallelism属性则尝试创建一个新的Worker线程,否则尝试唤醒一个空闲的Worker线程。

     另外从其tryAddWorker方法的实现可知,ForkJoinPool下线程池的最大线程数就是parallelism,不可能大于parallelism,可参考ADD_WORKER的调用链,如下:

有一种情形除外,某个ForkJoinTask通过awaitJoin方法阻塞了当前Worker线程的执行,如果当前WorkQueue中还有其他未执行的任务,则会创建新的Worker线程,导致总的线程数超过了parallelism,可参考实际创建Worker线程的creatWorker方法的调用链路,如下:

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

这几个方法的实现如下: 

//如果task是上一次插入的且将其从队列成功移除,则返回true,否则返回false
final boolean tryExternalUnpush(ForkJoinTask task) {
        WorkQueue[] ws; WorkQueue w; ForkJoinTask[] a; int m, s;
        int r = ThreadLocalRandom.getProbe();
        if ((ws = workQueues) != null && (m = ws.length - 1) >= 0 &&  //线程池已初始化
            (w = ws[m & r & SQMASK]) != null && //关联的WorkQueue非空
            (a = w.array) != null && (s = w.top) != w.base) { // 关联的WorkQueue包含有未执行的任务
            //j是上一次插入到数组中的索引
            long j = (((a.length - 1) & (s - 1)) << ASHIFT) + ABASE;
            if (U.compareAndSwapInt(w, QLOCK, 0, 1)) { //队列加锁
                if (w.top == s && w.array == a && //top和array属性未变更
                    U.getObject(a, j) == task && //如果上一次插入到数组中的任务就是task
                    U.compareAndSwapObject(a, j, task, null)) { //成功将其修改为null
                    U.putOrderedInt(w, QTOP, s - 1); //top属性减1
                    U.putOrderedInt(w, QLOCK, 0); //队列解锁
                    return true;
                }
                U.compareAndSwapInt(w, QLOCK, 1, 0);//队列解锁
            }
        }
        return false;
    }


final void externalPush(ForkJoinTask task) {
        WorkQueue[] ws; WorkQueue q; int m;
        int r = ThreadLocalRandom.getProbe();
        int rs = runState; //runState的初始值为0
        if ((ws = workQueues) != null && (m = (ws.length - 1)) >= 0 && //如果workQueues非空,该属性默认为null,说明线程池已初始化
            (q = ws[m & r & SQMASK]) != null && //计算存放任务的WorkQueue,如果对应的WorkQueue非空
            r != 0 && rs > 0 &&  //r不等于0说明当前线程的probe属性已初始化,rs大于0说明线程池已初始化且是正常运行的
            U.compareAndSwapInt(q, QLOCK, 0, 1)) { //对WorkQueue加锁
            ForkJoinTask[] a; int am, n, s;
            if ((a = q.array) != null && //保存任务的数组非空且有可用空间
                (am = a.length - 1) > (n = (s = q.top) - q.base)) {
                //计算保存的位置并保存到数组中
                int j = ((am & s) << ASHIFT) + ABASE;
                U.putOrderedObject(a, j, task);
                U.putOrderedInt(q, QTOP, s + 1); //top属性加1
                U.putIntVolatile(q, QLOCK, 0); //解锁
                if (n <= 1)
                    //原任务队列是空的,此时新增了一个任务,则尝试新增Worker或者唤醒空闲的Worker
                    signalWork(ws, q);
                return;
            }
            //WorkQueue解锁
            U.compareAndSwapInt(q, QLOCK, 1, 0);
        }
        //初始化调用线程的Probe,线程池和关联的WorkQueue
        //如果已初始化,则将任务保存到WorkQueue中
        externalSubmit(task);
    }

private void externalSubmit(ForkJoinTask task) {
        int r;                                    // initialize caller's probe
        if ((r = ThreadLocalRandom.getProbe()) == 0) { //初始化调用线程的Probe
            ThreadLocalRandom.localInit();
            r = ThreadLocalRandom.getProbe();
        }
        for (;;) {
            WorkQueue[] ws; WorkQueue q; int rs, m, k;
            boolean move = false;
            if ((rs = runState) < 0) { //如果线程池已关闭,则尝试终止,并抛出异常拒绝此次任务
                tryTerminate(false, false);     // help terminate
                throw new RejectedExecutionException();
            }
            else if ((rs & STARTED) == 0 ||     //如果线程池还未启动,未初始化
                     ((ws = workQueues) == null || (m = ws.length - 1) < 0)) {
                int ns = 0;
                rs = lockRunState(); //加锁
                try {
                    if ((rs & STARTED) == 0) { //再次校验未初始化,
                        U.compareAndSwapObject(this, STEALCOUNTER, null,
                                               new AtomicLong()); //初始化stealCounter属性
                        //获取并行度,计算对应的数组长度
                        int p = config & SMASK; // ensure at least 2 slots
                        int n = (p > 1) ? p - 1 : 1;
                        //p是3,即4核,n为2时,计算的结果是8
                        //p是7,即8核,n为6时,计算的结果是16,算出来的n是大于2n的最小的2的整数次幂的值
                        n |= n >>> 1; n |= n >>> 2;  n |= n >>> 4;
                        n |= n >>> 8; n |= n >>> 16; n = (n + 1) << 1;
                        //初始化workQueues
                        workQueues = new WorkQueue[n];
                        ns = STARTED;
                    }
                } finally {
                    //将线程池标记为已启动
                    unlockRunState(rs, (rs & ~RSLOCK) | ns);
                }
            }
            //线程池已启动
            else if ((q = ws[k = r & m & SQMASK]) != null) {
                //关联的WorkQueue不为null
                if (q.qlock == 0 && U.compareAndSwapInt(q, QLOCK, 0, 1)) { //将WorkQueue加锁
                    ForkJoinTask[] a = q.array;
                    int s = q.top;
                    boolean submitted = false; // initial submission or resizing
                    try {                      // locked version of push
                        if ((a != null && a.length > s + 1 - q.base) || //如果任务数组有剩余空间
                            (a = q.growArray()) != null) { //如果任务数组中没有剩余空间,则扩容
                            //计算任务数组中保存的位置并保存
                            int j = (((a.length - 1) & s) << ASHIFT) + ABASE;
                            U.putOrderedObject(a, j, task);
                            U.putOrderedInt(q, QTOP, s + 1);//top属性加1
                            submitted = true;
                        }
                    } finally {
                        //解锁
                        U.compareAndSwapInt(q, QLOCK, 1, 0);
                    }
                    if (submitted) { //如果任务已经提交到WorkQueue中
                        signalWork(ws, q); //新增Worker或者唤醒空闲的Worker
                        return;
                    }
                }
                //WorkQueue加锁失败
                move = true;                   // move on failure
            }
            //关联的WorkQueue为null
            else if (((rs = runState) & RSLOCK) == 0) { //线程池未加锁
                q = new WorkQueue(this, null);
                q.hint = r; //使用当前线程的probe初始化hint
                q.config = k | SHARED_QUEUE; //模式是共享的,即不属于某个特定的Worker,k表示该WorkQueue在数组中的位置
                q.scanState = INACTIVE;
                rs = lockRunState();           //加锁
                if (rs > 0 &&  (ws = workQueues) != null && //线程池已启动且workQueues非空
                    k < ws.length && ws[k] == null) //再次校验关联的WorkQueue为null
                    ws[k] = q;                 //将新的WorkQueue保存起来
                unlockRunState(rs, rs & ~RSLOCK); //解锁,下一次for循环就将任务保存到该WorkQueue中
            }
            else
                move = true;                   // move if busy
            if (move) //如果WorkQueue加锁失败,则增加probe属性,下一次for循环则遍历下一个WorkQueue,即将该Task提交到其他的WorkQueue中
                r = ThreadLocalRandom.advanceProbe(r);
        }//for循环结束
    }

//如果当前总的线程数小于parallelism,则signalWork会尝试创建新的Worker线程
//如果当前有空闲的Worker线程,则尝试唤醒一个,如果没有空闲的则直接返回
final void signalWork(WorkQueue[] ws, WorkQueue q) {
        long c; int sp, i; WorkQueue v; Thread p;
        while ((c = ctl) < 0L) { //ctl初始化时使用-parallelism,为负值表示活跃的线程数小于线程池初始化时设置的并行度要求
            if ((sp = (int)c) == 0) {                  //取低32位的值,如果为0,则活跃线程数等于总的线程数,即没有空闲的线程数
                if ((c & ADD_WORKER) != 0L)    //不等于0,说明总的线程数小于parallelism属性,可以新增线程
                    tryAddWorker(c); //尝试创建新线程
                //只要没有空闲的线程,此处就break,终止while循环    
                break;
            }
            //sp不等于0,即有空闲的线程,sp等于ctl的低32位
            //ctl的最低16位保存最近空闲的Worker线程关联的WorkQueue在数组中的索引
            if (ws == null)                            //线程池未初始化或者已终止
                break;
            if (ws.length <= (i = sp & SMASK))         //线程池已终止
                break;
            if ((v = ws[i]) == null)                   //线程池在终止的过程中
                break;
            //sp加SS_SEQ,非INACTIVE就是最高位0,再加31个1
            //此处将空闲WorkQueue的INACTIVE表示去除,变成正常的激活状态   
            int vs = (sp + SS_SEQ) & ~INACTIVE;        // next scanState
            int d = sp - v.scanState;                  // screen CAS
            //AC加1,UC_MASK取高32位的值,SP_MASK取低32位的值
            //stackPred是v被标记成INACTIVE时ctl的低32位,可能保存着在v之前空闲的WorkQueue在数组中的索引
            long nc = (UC_MASK & (c + AC_UNIT)) | (SP_MASK & v.stackPred);
            if (d == 0 && U.compareAndSwapLong(this, CTL, c, nc)) {
                //d等于0说明WorkQueue v关联的Worker是最近才空闲的
                //修改ctl属性成功
                v.scanState = vs;                      //将WorkQueue v标记成已激活
                if ((p = v.parker) != null)
                    U.unpark(p); //唤醒等待的线程
                break;
            }
            //如果d不等于0或者上述CAS修改失败,即已经有一个空闲Worker被其他线程给激活了
            if (q != null && q.base == q.top)          //任务队列为空,没有待执行的任务了,不需要激活空闲Worker或者创建新线程了
                break;
            //如果if不成立则继续下一次for循环
        } //while循环结束
    }

//尝试增加新线程
private void tryAddWorker(long c) {
        boolean add = false;
        do {
            //AC和TC都加1
             long nc = ((AC_MASK & (c + AC_UNIT)) |
                       (TC_MASK & (c + TC_UNIT)));
            if (ctl == c) { //如果ctl未变更
                int rs, stop;                 // check if terminating
                if ((stop = (rs = lockRunState()) & STOP) == 0) //加锁成功且线程池未终止,则修改ctl
                    add = U.compareAndSwapLong(this, CTL, c, nc);
                unlockRunState(rs, rs & ~RSLOCK); //解锁
                if (stop != 0) //如果线程池已终止,则终止while循环
                    break;
                if (add) {
                    //ctl修改成功,创建新的Worker
                    createWorker();
                    break;
                }
            }
            //重新读取ctl,如果依然可以新增线程且空闲线程数为0,则继续下一次for循环新增Worker
        } while (((c = ctl) & ADD_WORKER) != 0L && (int)c == 0);
    }

//创建新的Worker,如果创建失败或者启动执行异常则通过deregisterWorker方法通知线程池将其解除注册
private boolean createWorker() {
        ForkJoinWorkerThreadFactory fac = factory;
        Throwable ex = null;
        ForkJoinWorkerThread wt = null;
        try {
            if (fac != null && (wt = fac.newThread(this)) != null) {
                wt.start(); //通过ThreadFactory创建一个新的Worker,并启动线程的执行
                return true;
            }
        } catch (Throwable rex) {
            ex = rex;
        }
        //创建的过程中有异常,通知线程池将其解除注册
        deregisterWorker(wt, ex);
        return false;
    }

上述代码涉及ctl的位运算,可参考如下测试用例:

// Active counts
    private static final int  AC_SHIFT   = 48;
    private static final long AC_UNIT    = 0x0001L << AC_SHIFT;
    private static final long AC_MASK    = 0xffffL << AC_SHIFT;

    // Total counts
    private static final int  TC_SHIFT   = 32;
    private static final long TC_UNIT    = 0x0001L << TC_SHIFT;
    private static final long TC_MASK    = 0xffffL << TC_SHIFT;
    private static final long ADD_WORKER = 0x0001L << (TC_SHIFT + 15); // sign

    @Test
    public void test16() throws Exception {
        long np=-3l;
        //初始状态
        long ctl=((np << AC_SHIFT) & AC_MASK) | ((np << TC_SHIFT) & TC_MASK);
        System.out.println(Long.toBinaryString(ctl));
        System.out.println(ctl & ADD_WORKER);
        System.out.println((short)(ctl >>> TC_SHIFT));

        //新增一个线程
        ctl = ((AC_MASK & (ctl + AC_UNIT)) |
                (TC_MASK & (ctl + TC_UNIT)));
        System.out.println(Long.toBinaryString(ctl));
        System.out.println(ctl & ADD_WORKER);
        System.out.println((short)(ctl >>> TC_SHIFT));

        //新增一个线程
        ctl = ((AC_MASK & (ctl + AC_UNIT)) |
                (TC_MASK & (ctl + TC_UNIT)));
        System.out.println(Long.toBinaryString(ctl));
        System.out.println(ctl & ADD_WORKER);
        System.out.println((short)(ctl >>> TC_SHIFT));

        //新增一个线程
        ctl = ((AC_MASK & (ctl + AC_UNIT)) |
                (TC_MASK & (ctl + TC_UNIT)));
        System.out.println(Long.toBinaryString(ctl));
        System.out.println(ctl & ADD_WORKER); //新增了3个线程后等于0
        System.out.println((short)(ctl >>> TC_SHIFT));
    }

 

5、lockRunState / unlockRunState

      lockRunState将当前线程池加锁,如果当前runState已加锁或者CAS加锁失败则调用awaitRunStateLock等待锁释放并加锁;awaitRunStateLock方法会阻塞当前线程,直到锁释放被唤醒,然后尝试获取锁,如果获取失败则继续阻塞,直到获取成功为止;unlockRunState方法将当前线程池解锁,如果oldRunState跟当前的runstate属性不一致,说明有某个线程在等待获取锁,在runstate上加上了RSIGNAL标识,则直接修改runstate,去掉RSIGNAL标识,并唤醒所有等待获取锁的线程。

      线程池加锁和解锁是成对出现的,用于线程池初始化或者终止,修改WorkerQueue数组,修改ctl属性时使用,参考lockRunState的调用链,如下:

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

其实现如下: 

//执行加锁
private int lockRunState() {
        int rs;
        return ((((rs = runState) & RSLOCK) != 0 || //如果已经加锁
                 !U.compareAndSwapInt(this, RUNSTATE, rs, rs |= RSLOCK)) ? //如果未加锁则CAS加锁
                //如果加锁失败调用awaitRunStateLock,阻塞当前线程等待获取锁,否则返回rs
                awaitRunStateLock() : rs);
    }
//执行解锁
 private void unlockRunState(int oldRunState, int newRunState) {
        if (!U.compareAndSwapInt(this, RUNSTATE, oldRunState, newRunState)) {
            //如果cas修改失败,只能是oldRunState发生改变了,加上了RSIGNAL
            //所以此处是直接重置runState,去除RSLOCK和RSIGNAL,并唤醒所有等待获取锁的线程
            Object lock = stealCounter;
            runState = newRunState;              // clears RSIGNAL bit
            if (lock != null)
                //唤醒所有等待获取锁的线程
                synchronized (lock) { lock.notifyAll(); }
        }
    }

//阻塞当前线程,直到锁释放被唤醒,然后尝试获取锁
private int awaitRunStateLock() {
        Object lock;
        boolean wasInterrupted = false;
        //SPINS默认是0
        for (int spins = SPINS, r = 0, rs, ns;;) {
            if (((rs = runState) & RSLOCK) == 0) { //如果未加锁
                if (U.compareAndSwapInt(this, RUNSTATE, rs, ns = rs | RSLOCK)) {
                    //尝试加锁成功
                    if (wasInterrupted) {
                        try {
                            //将当前线程标记为中断
                            Thread.currentThread().interrupt();
                        } catch (SecurityException ignore) {
                        }
                    }
                    return ns;
                }
            }
            //如果已加锁
            else if (r == 0)
                //初始化r
                r = ThreadLocalRandom.nextSecondarySeed();
            else if (spins > 0) {
                //自旋等待
                r ^= r << 6; r ^= r >>> 21; r ^= r << 7; // xorshift
                if (r >= 0)
                    --spins;
            }
            //spins等于0
            else if ((rs & STARTED) == 0   //线程池未初始化
                  || (lock = stealCounter) == null)
                Thread.yield();   //执行yeild,等待线程池初始化
            //线程池已初始化    
            else if (U.compareAndSwapInt(this, RUNSTATE, rs, rs | RSIGNAL)) { //状态加上RSIGNAL
                synchronized (lock) {
                    if ((runState & RSIGNAL) != 0) { //再次校验
                        try {
                            lock.wait(); //阻塞当前线程
                        } catch (InterruptedException ie) {
                            if (!(Thread.currentThread() instanceof
                                  ForkJoinWorkerThread))
                                wasInterrupted = true;
                        }
                    }
                    else
                        //如果RSIGNAL标识没了,说明unlockRunState将该标识清除了
                        //此时还在synchronized代码块中未释放锁,所以unlockRunState中的synchronized会被阻塞
                        //唤醒所有等待获取锁的线程
                        lock.notifyAll();
                }
                //下一次for循环会尝试获取锁
            }
        }//for循环结束
    }

 

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