一直都是使用Executors.newFixedThreadPool(10)这样的方式来创建线程池。
这个工厂方法实际创建ThreadPoolExecutor对象,其构造函数有三个主要参数
corePoolSize
maximumPoolSize
和workQueue
newFixedThreadPool的时候ThreadPoolExecutor的三个构造参数分别为10,10,new LinkedBlockingQueue<Runnable>();
一直都错误地理解
他的工作方式,及新加入一个任务后,如果当前线程数达到maximumPoolSize后,就放入队列中等待执行。
想当然地认为只要参数设置为1,10,new LinkedBlockingQueue<Runnable>()后,线程池就会最大同时运行10个任务,没任务的时候就只有一个线程。
错!错!错!
正确的是------当有新任务时,若当前线程数等于或大于corePoolSize时,任务会被加入到队列中,如果加入成功,则稍后有空闲线程执行;如果失败,则创建一个新的线程来执行,若线程数达到maximumPoolSize则任务会被拒绝执行。
又由于LinkedBlockingQueue是个无界队列,所以这里maximumPoolSize设置是无效的。
呀!终于用对了!
javadoc文档的一部分:
所有 BlockingQueue
都可用于传输和保持提交的任务。可以使用此队列与池大小进行交互:
- 如果运行的线程少于 corePoolSize,则 Executor 始终首选添加新的线程,而不进行排队。
- 如果运行的线程等于或多于 corePoolSize,则 Executor 始终首选将请求加入队列,而不添加新的线程。
- 如果无法将请求加入队列,则创建新的线程,除非创建此线程超出 maximumPoolSize,在这种情况下,任务将被拒绝。
排队有三种通用策略:
- 直接提交。
工作队列的默认选项是
SynchronousQueue
,
它将任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败,因此会构造一个新的线程。此策略可以避免
在处理可能具有内部依赖性的请求集合时出现锁定。直接提交通常要求无界 maximumPoolSizes
以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
-
无界队列。
使用无界队列(例如,不具有预定义容量的
LinkedBlockingQueue
)
将导致在所有 corePoolSize 线程都忙的情况下将新任务加入队列。这样,创建的线程就不会超过
corePoolSize。(因此,maximumPoolSize
的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时,适合于使用无界队列;例如,在 Web
页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处理的平均数连续到达时,此策略允许无界线程具有增长的可能性。
-
有界队列。
当使用有限的 maximumPoolSizes 时,有界队列(如
ArrayBlockingQueue
)
有助于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限度地降低 CPU
使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果它们是 I/O
边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU
使用率较高,但是可能遇到不可接受的调度开销,这样也会降低吞吐量。
分享到:
相关推荐
ThreadPoolExecutor使用和思考
在《阿里巴巴java开发手册》中...另外由于前面几种方法内部也是通过ThreadPoolExecutor方式实现,使用ThreadPoolExecutor有助于大家明确线程池的运行规则,创建符合自己的业务场景需要的线程池,避免资源耗尽的风险。
ThreadPoolExecutor的使用和Android常见的4种线程池使用介绍
ThreadPoolExecutor源码解析.pdf
一个关于java 线程池的例子,也适合android
JDK1[1].5中的线程池(ThreadPoolExecutor)使用简介
ThreadPoolExecutor线程池,有详尽介绍,本人进行过测试,可以使用
NULL 博文链接:https://bijian1013.iteye.com/blog/2284676
ThreadPoolExecutor源码解析.md
(转)线程池:java_util_ThreadPoolExecutor 比较详细的介绍了ThreadPoolExecutor用法与属性
主要介绍了java ThreadPoolExecutor使用方法简单介绍的相关资料,需要的朋友可以参考下
主要为大家详细介绍了ThreadPoolExecutor线程池的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
1.资源简介:PyQt5中使用多线程模块QThread解决了PyQt5界面程序执行比较耗时操作时,程序卡顿出现的无响应以及界面输出无法实时显示的问题,采用线程池ThreadPoolExecutor解决了ping多个IP多任务耗时问题。...
JDK1.5中的线程池(java.util.concurrent.ThreadPoolExecutor)使用
在开发过程中,合理地使用线程池能够带来3个好处: 降低资源消耗。 通过重复利用已创建的线程降低线程创建和销毁造成的消耗; 提高响应速度。 当任务到达时,任务可以不需要等到线程创建就能立即执行; 提高...
线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor实战及其原理分析(下)线程池ThreadPoolExecutor...
介绍ThreadPoolExecutor中池和queue配合使用的机制
线程池执行器 使用多线程ThreadPoolExecutor从Web加载图像
提供工厂方法来创建不同类型的线程池,这篇文章主要介绍了Java ThreadPoolExecutor 线程池的使用介绍,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来...