RedSpider1 / concurrent

这是RedSpider社区成员原创与维护的Java多线程系列文章。

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

第12章线程池原理,JDK已更新线程池状态(runState)实现方式,但文中未表明对应版本,导致文中描述与常用版本情况不符引起误会。

opened this issue · comments

问题描述

《深入浅出Java多线程》第12章的 12.2.2 ThreadPoolExecutor的策略中,这里说到一个volatile int变量 runState 表示线程池状态。

但是查看JDK1.8中ThreadPoolExecutor的实现,并没有找到volatilerunState变量。

故线程池也有自己的状态。ThreadPoolExecutor类中定义了一个volatile int变量runState来表示线程池的状态 ,分别为RUNNING、SHUTDOWN、STOP、TIDYING 、TERMINATED。

具体情况

文中描述的 runState 初步判断,应该是JDK1.6中 ThreadPoolExecutor 的实现.

而在JDK1.8中线程池状态,是通过AtomicInteger类型的成员变量 ctl l获取。

获取的 ctl 值传入runStateOf 方法,与 ~CAPACITY 位与运算(CAPACITY是低29位全1的int变量)。

~CAPACITY在这里相当于掩码,用来获取ctl的高3位,表示线程池状态;而另外的低29位用于表示工作线程数

建议

  • 希望在文中标明一下版本,以免引起不必要的误会。
  • 如果能加上新版实现的介绍说明,那就更好啦。

附:JDK1.8中ThreadPoolExecutor的相关代码

    /**
     * The main pool control state, ctl, is an atomic integer packing
     * two conceptual fields
     *   workerCount, indicating the effective number of threads
     *   runState,    indicating whether running, shutting down etc
     *
     * In order to pack them into one int, we limit workerCount to
     * (2^29)-1 (about 500 million) threads rather than (2^31)-1 (2
     * billion) otherwise representable. If this is ever an issue in
     * the future, the variable can be changed to be an AtomicLong,
     * and the shift/mask constants below adjusted. But until the need
     * arises, this code is a bit faster and simpler using an int.
     *
     * The workerCount is the number of workers that have been
     * permitted to start and not permitted to stop.  The value may be
     * transiently different from the actual number of live threads,
     * for example when a ThreadFactory fails to create a thread when
     * asked, and when exiting threads are still performing
     * bookkeeping before terminating. The user-visible pool size is
     * reported as the current size of the workers set.
     *
     * The runState provides the main lifecycle control, taking on values:
     *
     *   RUNNING:  Accept new tasks and process queued tasks
     *   SHUTDOWN: Don't accept new tasks, but process queued tasks
     *   STOP:     Don't accept new tasks, don't process queued tasks,
     *             and interrupt in-progress tasks
     *   TIDYING:  All tasks have terminated, workerCount is zero,
     *             the thread transitioning to state TIDYING
     *             will run the terminated() hook method
     *   TERMINATED: terminated() has completed
     *    ……
     *   
     */
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));       //ctl变量记录状态
    private static final int COUNT_BITS = Integer.SIZE - 3;
    private static final int CAPACITY   = (1 << COUNT_BITS) - 1;

    // runState is stored in the high-order bits
    private static final int RUNNING    = -1 << COUNT_BITS;
    private static final int SHUTDOWN   =  0 << COUNT_BITS;
    private static final int STOP       =  1 << COUNT_BITS;
    private static final int TIDYING    =  2 << COUNT_BITS;
    private static final int TERMINATED =  3 << COUNT_BITS;

    // Packing and unpacking ctl
    private static int runStateOf(int c)     { return c & ~CAPACITY; }          // runStateOf方法,获取运行状态
    private static int workerCountOf(int c)  { return c & CAPACITY; }
    private static int ctlOf(int rs, int wc) { return rs | wc; }

感谢反馈,我们会直接改成新版本的。