Java8 ForkJoinPool(二) 源码解析

本文详细解析了Java8的ForkJoinPool,包括其定义、构造方法、任务提交(invoke/execute/submit/invokeAll)、externalPush/tryExternalUnpush方法以及lockRunState/unlockRunState的加锁解锁机制。ForkJoinPool通过多任务队列减少并发竞争,使用特定策略分配任务,并能灵活调整线程创建。
摘要由CSDN通过智能技术生成

目录

        1、定义

2、构造方法

3、invoke / execute / submit / invokeAll

4、externalPush / tryExternalUnpush

5、lockRunState / unlockRunState


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

1、定义

     ForkJoinPool的类继承关系如下:

   

该类包含的属性如下:

   //最高的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<ForkJoinPool>() {
                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相比,最后一
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值