JAVA-常用线程池执行的流程图

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

本文适合:

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

不适合:

完全没看过的,建议你先去看看其他基础文章 看过,却忘得差不多了,建议你先去回顾下

本文能给你的阅读回报

适合的读者,尽可能让你彻底明白 常用的线程池的知识相关点 不适合的读者,能有个不错的概念,神童另谈

废话少说,我们开始。

默认构造函数

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

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

corePoolSize,maximumPoolSize,workQueue 之间关系。

文字描述

1、当线程池中线程数小于 corePoolSize 时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。

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

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

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

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

6、当设置 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 的时候是一样的。区别就在于:

1、newSingleThreadExecutor 返回的 ExcutorService 在析构函数 finalize() 处会调用 shutdown() 2、如果我们没有对它调用 shutdown(),那么可以确保它在被回收时调用 shutdown() 来终止线程。

使用 ThreadFactory,可以改变线程的名称、线程组、优先级、守护进程状态,一般采用默认。

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

最后

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

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

经验分享 程序员 微信小程序 职场和发展