通俗易懂,各经常使用线程池执行的-流程图

做者:林冠宏 / 指尖下的幽灵java

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8git

博客:http://www.cnblogs.com/linguanh/github

GitHub : https://github.com/af913337456/并发

有时候花了大把时间去看一些东西却看不懂,是很 “ 蓝瘦 ” 的,花时间也是投资。

本文适合:函数

  • 曾了解过线程池却一直模模糊糊的人
  • 了解得差很少却对某些点依然疑惑的

不适合:spa

  • 彻底没看过的,建议你先去看看其余基础文章
  • 看过,却忘得差很少了,建议你先去回顾下

本文能给你的阅读回报

  • 适合的读者,尽量让你完全明白经常使用的线程池的知识相关点
  • 不适合的读者,能有个不错的概念,神童另谈

废话少说,咱们开始。下图,皆可自行保存,经常阅之。日久,根深蒂固线程

默认构造函数

public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler ) {
    ....
}
复制代码

绝对易懂的构造方法参数讲解

参数名 做用
corePoolSize 队列没满时,线程最大并发数
maximumPoolSizes 队列满后线程可以达到的最大并发数
keepAliveTime 空闲线程过多久被回收的时间限制
unit keepAliveTime 的时间单位
workQueue 阻塞的队列类型
RejectedExecutionHandler 超出 maximumPoolSizes + workQueue 时,任务会交给RejectedExecutionHandler来处理

文字描述

corePoolSize,maximumPoolSize,workQueue之间关系。3d

  • 当线程池中线程数小于corePoolSize时,新提交任务将建立一个新线程执行任务,即便此时线程池中存在空闲线程。代理

  • 当线程池中线程数达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行 。code

  • 当workQueue已满,且maximumPoolSize > corePoolSize时,新提交任务会建立新线程执行任务。

  • 当workQueue已满,且提交任务数超过maximumPoolSize,任务由RejectedExecutionHandler处理。

  • 当线程池中线程数超过corePoolSize,且超过这部分的空闲时间达到keepAliveTime时,回收这些线程。

  • 当设置allowCoreThreadTimeOut(true)时,线程池中corePoolSize范围内的线程空闲时间达到keepAliveTime也将回收。

通常流程图

newFixedThreadPool 流程图

public static ExecutorService newFixedThreadPool(int nThreads){
    return new ThreadPoolExecutor(
            nThreads,   // corePoolSize
            nThreads,   // maximumPoolSize == corePoolSize
            0L,         // 空闲时间限制是 0
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>() // 无界阻塞队列
        );
}
复制代码

newCacheThreadPool 流程图

public static ExecutorService newCachedThreadPool(){
    return new ThreadPoolExecutor(
        0,                  // corePoolSoze == 0
        Integer.MAX_VALUE,  // maximumPoolSize 很是大
        60L,                // 空闲断定是60 秒
        TimeUnit.SECONDS,
        // 神奇的无存储空间阻塞队列,每一个 put 必需要等待一个 take
        new SynchronousQueue<Runnable>()  
    );
}

复制代码

newSingleThreadPool 流程图

public static ExecutorService newSingleThreadExecutor() {
        return 
            new FinalizableDelegatedExecutorService
                (
                    new ThreadPoolExecutor
                        (
                            1,
                            1,
                            0L,
                            TimeUnit.MILLISECONDS,
                            new LinkedBlockingQueue<Runnable>(),
                            threadFactory
                        )
                );
    }
复制代码

能够看到除了多了个 FinalizableDelegatedExecutorService 代理,其初始化和 newFiexdThreadPool 的 nThreads = 1 的时候是同样的。 区别就在于:

  • newSingleThreadExecutor返回的ExcutorService在析构函数finalize()处会调用shutdown()
  • 若是咱们没有对它调用shutdown(),那么能够确保它在被回收时调用shutdown()来终止线程。

使用ThreadFactory,能够改变线程的名称、线程组、优先级、守护进程状态,通常采用默认。

流程图略,请参考 newFiexdThreadPool,这里再也不累赘。

最后

还有一个定时任务线程池ScheduledThreadPool

它用来处理延时或定时任务,不经常使用

相关文章
相关标签/搜索