有时候花了大把时间去看一些东西却看不懂,是很 “ 蓝瘦 ” 的,花时间也是投资。
本文适合:
曾了解过线程池却一直模模糊糊的人 了解得差不多却对某些点依然疑惑的
不适合:
完全没看过的,建议你先去看看其他基础文章 看过,却忘得差不多了,建议你先去回顾下
适合的读者,尽可能让你彻底明白 常用的线程池
的知识相关点 不适合的读者,能有个不错的概念,神童另谈
废话少说,我们开始。
public ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) { ....}复制代码
1、当线程池中线程数小于corePoolSize时,新提交任务将创建一个新线程执行任务,即使此时线程池中存在空闲线程。
2、当线程池中线程数达到corePoolSize时,新提交任务将被放入workQueue中,等待线程池中任务调度执行 。
3、当workQueue已满,且maximumPoolSize > corePoolSize时,新提交任务会创建新线程执行任务。
4、当workQueue已满,且提交任务数超过maximumPoolSize,任务由RejectedExecutionHandler处理。
5、当线程池中线程数超过corePoolSize,且超过这部分的空闲时间达到keepAliveTime时,回收这些线程。
6、当设置 allowCoreThreadTimeOut(true)时,线程池中corePoolSize范围内的线程空闲时间达到keepAliveTime也将回收。
public static ExecutorService newFixedThreadPool(int nThreads){ return new ThreadPoolExecutor( nThreads, // corePoolSize nThreads, // maximumPoolSize == corePoolSize 0L, // 空闲时间限制是 0 TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>() // 无界阻塞队列 );}
public static ExecutorService newCachedThreadPool(){ return new ThreadPoolExecutor( 0, // corePoolSoze == 0 Integer.MAX_VALUE, // maximumPoolSize 非常大 60L, // 空闲判定是60 秒 TimeUnit.SECONDS, // 神奇的无存储空间阻塞队列,每个 put 必须要等待一个 take new SynchronousQueue<Runnable>() );}
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
它用来处理延时或定时任务,不常用
原文:
juejin.im/post/5a28b37c6fb9a044fc44a103
干货文章转发起来,让大家一起学习
更多技术干货