ThreadPoolExecutor浅析

首先查看完整的构造函数

public ThreadPoolExecutor(int corePoolSize,

                              int maximumPoolSize,

                              long keepAliveTime,

                              TimeUnit unit,

                              BlockingQueue<Runnable> workQueue,

                              ThreadFactory threadFactory,

                              RejectedExecutionHandler handler)

线程池内部变量

poolSize: 线程池当前正在运行的线程数目

workers: 一个hashset,存储线程池当前正在运行的线程,存储的类型是Worker,一个ThreadPoolExecutor的内部类

keepAliveTime:线程在获取任务时最大等待的时间。如果超过该时间仍然得不到任务,则该线程就会终止,并被移出线程池

                            这里分2种情况,如果allowCoreThreadTimeOut为true则对任意线程都是一样,如果为false,则只有非核心线程

                            才会被移除(超过corePoolSize的那部分线程)

corePoolSize:核心线程数,即使线程空闲也不会被移除

maximumPoolSize:最大线程数

workQueue:存储task的容器

threadFactory:生成线程的线程工厂

handler:任务被线程池丢弃时的处理策略

runState: 线程池运行的状态有4个值,RUNNING,SHUTDOWN,STOP,TERMINATE

执行流程

初始状态 poolSize=0

客户端调用execute或submit...

以下分析均在RUNNING状态下

某个时刻之前,客户端一直在向线程池提交task

1. 如果poolSize < corePoolSize, 则立即创建新线程并运行之,poolSize自增1。task不会加入workQueue,此后该线程(ThreadPoolExecutor的内部类Worker)执行其循环体不断从workQueue取task来执行


2. 如果poolSize >= corePoolSize,则尝试将task放入workQueue,

2.1 如果队列未满,则将task加入workQueue,但不创建新线程

2.2 如果workQueue已满,则不加入任务队列并立即返回,此时

2.2.1 如果poolSize < maximumPoolSize, 则情况和1一样

2.2.2 否则调用handler(RejectedExecutionHandler )来处理该task


某个时刻之后客户端不再加入任何任务,则

当某个线程从workQueue获取task时发现: 如果workQueue已经为空或者 allowCoreThreadTimeOut为true 并且 poolSize > coreSize时

即workQueue.isEmpty() || (allowCoreThreadTimeOut && poolSize > Math.max(1, corePoolSize)

则该线程执行结束,从线程池移除,poolSize减1


对于runState,其状态及含义如下:(摘自jdk源码)

 /**
     * runState provides the main lifecyle 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
     *   TERMINATED: Same as STOP, plus all threads have terminated
     *
     * The numerical order among these values matters, to allow
     * ordered comparisons. The runState monotonically increases over
     * time, but need not hit each state. The transitions are:
     *
     * RUNNING -> SHUTDOWN
     *    On invocation of shutdown(), perhaps implicitly in finalize()
     * (RUNNING or SHUTDOWN) -> STOP
     *    On invocation of shutdownNow()
     * SHUTDOWN -> TERMINATED
     *    When both queue and pool are empty
     * STOP -> TERMINATED
     *    When pool is empty
     */
    volatile int runState;
    static final int RUNNING    = 0;
    static final int SHUTDOWN   = 1;
    static final int STOP       = 2;
    static final int TERMINATED = 3;

                 

PS:

Executors 的几个方法newFixThreadPool,newCacheThredPool都是从ThreadPoolExecutor构造而来,对于前者

corePoolSize, maxPoolSize相等

对于后者两者分别为 0, Integer.MAX_VALUE                














你可能感兴趣的:(java,线程池)