美文网首页
ThreadPoolExecutor详解

ThreadPoolExecutor详解

作者: simler | 来源:发表于2018-03-29 15:02 被阅读100次

    一、线程池参数介绍

     /**
         * Creates a new {@code ThreadPoolExecutor} with the given initial
         * parameters.
         *
         * @param corePoolSize the number of threads to keep in the pool, even
         *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
         * @param maximumPoolSize the maximum number of threads to allow in the
         *        pool
         * @param keepAliveTime when the number of threads is greater than
         *        the core, this is the maximum time that excess idle threads
         *        will wait for new tasks before terminating.
         * @param unit the time unit for the {@code keepAliveTime} argument
         * @param workQueue the queue to use for holding tasks before they are
         *        executed.  This queue will hold only the {@code Runnable}
         *        tasks submitted by the {@code execute} method.
         * @param threadFactory the factory to use when the executor
         *        creates a new thread
         * @param handler the handler to use when execution is blocked
         *        because the thread bounds and queue capacities are reached
         * @throws IllegalArgumentException if one of the following holds:<br>
         *         {@code corePoolSize < 0}<br>
         *         {@code keepAliveTime < 0}<br>
         *         {@code maximumPoolSize <= 0}<br>
         *         {@code maximumPoolSize < corePoolSize}
         * @throws NullPointerException if {@code workQueue}
         *         or {@code threadFactory} or {@code handler} is null
         */
        public ThreadPoolExecutor(int corePoolSize,
                                  int maximumPoolSize,
                                  long keepAliveTime,
                                  TimeUnit unit,
                                  BlockingQueue<Runnable> workQueue,
                                  ThreadFactory threadFactory,
                                  RejectedExecutionHandler handler) {
            if (corePoolSize < 0 ||
                maximumPoolSize <= 0 ||
                maximumPoolSize < corePoolSize ||
                keepAliveTime < 0)
                throw new IllegalArgumentException();
            if (workQueue == null || threadFactory == null || handler == null)
                throw new NullPointerException();
            this.corePoolSize = corePoolSize;
            this.maximumPoolSize = maximumPoolSize;
            this.workQueue = workQueue;
            this.keepAliveTime = unit.toNanos(keepAliveTime);
            this.threadFactory = threadFactory;
            this.handler = handler;
        }
    
    • corePoolSize: 池内线程初始值与最小值,就算是空闲状态,也会保持该数量线程。

    CPU密集型任务,IO密集型任务和混合型任务:
    任务性质不同的任务可以用不同规模的线程池分开处理。CPU密集型任务配置尽可能小的线程,如配置Ncpu+1个线程的线程池。IO密集型任务则由于线程并不是一直在执行任务,则配置尽可能多的线程,如2Ncpu。混合型的任务,如果可以拆分,则将其拆分成一个CPU密集型任务和一个IO密集型任务,只要这两个任务执行的时间相差不是太大,那么分解后执行的吞吐率要高于串行执行的吞吐率,如果这两个任务执行时间相差太大,则没必要进行分解。我们可以通过Runtime.getRuntime().availableProcessors()方法获得当前设备的CPU个数。如果是IO密集型任务,参考值可以设置为2NCPU

    • maximumPoolSize: 线程最大值,线程的增长始终不会超过该值。
    • keepAliveTime: 当池内线程数高于corePoolSize时,经过多少时间多余的空闲线程才会被回收。回收前处于wait状态
    • unit: 时间单位,可以使用TimeUnit的实例,如TimeUnit.MILLISECONDS
    • workQueue: 待入任务(Runnable)的等待场所,该参数主要影响调度策略,如公平与否,是否产生饿死(starving)
    • threadFactory: 线程工厂类,有默认实现,如果有自定义的需要则需要自己实现ThreadFactory接口并作为参数传入。
    • RejectedExecutionHandler: 线程池的拒绝策略
      • AbortPolicy:对拒绝任务抛弃处理,并且抛出异常。【默认线程池拒绝策略】
      • DiscardPolicy:对拒绝任务直接无声抛弃,没有异常信息。
      • DiscardOldestPolicy:对拒绝任务不抛弃,而是抛弃队列里面等待最久的一个线程,然后把拒绝任务加到队列。
      • CallerRunsPolicy:这个策略重试添加当前的任务,他会自动重复调用 execute() 方法,直到成功。

    二、线程池执行流程

    1.png
    1. 如果线程池中的线程数量少于corePoolSize,就创建新的线程来执行新添加的任务
    2. 如果线程池中的线程数量大于等于corePoolSize,但队列workQueue未满,则将新添加的任务放到workQueue中
    3. 如果线程池中的线程数量大于等于corePoolSize,且队列workQueue已满,但线程池中的线程数量小于maximumPoolSize,则会创建新的线程来处理被添加的任务
    4. 如果线程池中的线程数量等于了maximumPoolSize,就用RejectedExecutionHandler来执行拒绝策略

    三、线程池状态

    • RUNNING:接受新的任务,处理队列任务;
    • SHUTDOWN:不在接受新的任务,处理队列任务;
    • STOP:不在接受新任务,不处理队列任务,中断正在执行的任务线程;
    • TIDYING:所有的任务已经结束,任务线程为0,线程转换到TIDYING;
    • TERMINATED:线程池已将结束,即terminated()方法执行完。

    四、线程的生命周期

    1. 新建(new Thread)
      当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。
      例如:Thread t1=new Thread();

    2. 就绪(runnable)
      线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队等候得到CPU资源。例如:t1.start();

    3. 运行(running)
      线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有优先级更高的线程进入,线程将一直运行到结束。

    4. 死亡(dead)
      当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态等待执行。
      自然终止:正常运行run()方法后终止
      异常终止:调用stop()方法让一个线程终止运行

    5. 堵塞(blocked)
      由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。
      正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。
      正在等待:调用wait()方法。(调用motify()方法回到就绪状态)
      被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)

    相关文章

      网友评论

          本文标题:ThreadPoolExecutor详解

          本文链接:https://www.haomeiwen.com/subject/fkvmcftx.html