一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第14天,点击查看活动详情。
本文主要介绍常用线程池相关的知识点
awaitTermination、shutdown、shutdownNow
优雅的关闭,用shutdown()
想立马关闭,并得到未执行任务列表,用shutdownNow()
优雅的关闭,并允许关闭声明后新任务能提交,用awaitTermination()
可以关闭执行程序服务,这将导致它拒绝新任务。提供了两种不同的方法来关闭执行程序服务。shutdown() 方法将允许在终止之前执行以前提交的任务,而 shutdownNow() 方法将阻止等待任务启动并尝试停止当前正在执行的任务。终止后,执行程序没有正在执行的任务,没有等待执行的任务,并且不能提交任何新任务。应关闭未使用的执行程序服务,以允许回收其资源。
启动有序关闭,其中执行以前提交的任务,但不接受任何新任务。如果已关闭,则调用不会产生其他影响。 此方法不等待以前提交的任务完成执行。使用 awaitTermination 来执行此操作。
newCachedThreadPool()
这个线程池newCachedThreadPool(),阿里不推荐使用。为什么会这样呢?最容易发生的问题是内存溢出,因为通过对线程池的分析我们知道,所有任务会一直往队列里面放,直到放不下了才可能开始拒绝,但是newFixedThreadPool、newSingleThreadExecutor这些线程池初始化的队列都是LinkedBlockingQueue,也就是无界队列,cache缓存的任务数可能会无限增长。newCachedThreadPool这个线程池,没有使用无界队列,使用的是一个即进即出的队列,但是这个线程池的最大线程数是Integer.MAX_VALUE,线程数如果一直增长,同样会内存溢出。
所以综上所述,cache相当于是工作者线程无限制,容易导致CPU飙高;其它两个相当于处理的任务(队列)无限个,容易导致内存溢出
总结
对于线程和线程池的使用,一定要小心谨慎,需要弄清楚其中原理,在适当的场景使用适当的线程池,是程序员需要具备的基本分析能力。比如缩容的newCachedThreadPool,当我们使用arthas进行分析观察时,会发现线程一会有,一会没有。这是正常的,因为当资源空闲时,线程就会被回收。知道其中原理后,也不会对这个现象大惊小怪了