当前位置: 首页 > news >正文

线程池

一. 好处

  1. 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  2. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。
  3. 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。

二. 线程池的使用

java.util.concurrent.ThreadPoolExecutor类.

2.1 创建线程池

创建一个线程池有以下4个构造函数, 其中前3个都最终调用了最后一个.

image

image

2.2 线程池的主要工作机制

  1. 提交新任务到线程池
  2. 若核心池未满,创建一个工作线程来执行任务. 若已满,下一步.
  3. 若工作队列未满, 新提交的任务入队. 若已满,下一步.
  4. 若线程池未满,创建一个工作线程来执行任务. 若已满,交给饱和策略来处理.

image

image

2.3 线程池中线程的状态

image

  • running, 调用了shutdown()后变为shutdown. 当队列为空且线程池为空, tidying态
  • running或shutdown, 调用了shutdownNow()后变为stop. 当线程池为空时, tidying态.
  • tidying, 调用terminated()后变为terminated.

三. 合理配置线程池

3.1 任务的性质

CPU密集型任务, 尽可能少的线程. 如 Ncpu+1个线程.

IO密集型任务, 由于线程不是一直在执行任务, 可配置尽可能多的线程. 如 2*Ncpu

混合型任务,如果可以拆分为两个执行时间相差不太大的CPU密集型任务和IO密集型任务,分解后的吞吐率要高于串行的吞吐率。如果执行时间相差太大,就没必要分解。

3.2 优先级

PriorityBlockingQueue. 优先级高的任务先执行。 但如果一直有高优先级的任务加入,低优先级的任务可能永远无法执行。

3.3 执行时间

执行时间不同的线程,可以交给不同规模的线程池,也可以使用优先队列,优先执行时间较短的线程。

3.4 数据库连接

依赖数据库连接的任务,因为线程提交SQL之后需要等待数据库返回结果,等待时间越长,CPU空闲时间越多。所以线程数应该设置大一些,才能更好地利用CPU。

3.5 有界队列

建议使用有界队列。有界队列能增加系统的稳定性和预警能力。可以根据需要设置大一些,比如几千。

如果后台线程池里的线程全部要向数据库查询和插入数据,一旦数据库出了问题,导致SQL很慢,线程阻塞,就会大量积压。如果这时设置为无界队列,就有可能撑满内存,导致整个系统不可用。

四、线程池的监控

  • taskCount:线程池需要执行的任务数量。
  • completedTaskCount:线程池在运行过程中已完成的任务数量。小于或等于taskCount。
  • largestPoolSize:线程池曾经创建过的最大线程数量。通过这个数据可以知道线程池是否满过。如等于线程池的最大大小,则表示线程池曾经满了。
  • getPoolSize:线程池的线程数量。如果线程池不销毁的话,池里的线程不会自动销毁,所以这个大小只增不+ getActiveCount:获取活动的线程数。

通过扩展线程池进行监控。通过继承线程池并重写线程池的beforeExecute,afterExecute和terminated方法,我们可以在任务执行前,执行后和线程池关闭前干一些事情。如监控任务的平均执行时间,最大执行时间和最小执行时间等。这几个方法在线程池里是空方法。

 

 

参考资料

http://www.infoq.com/cn/articles/java-threadPool

http://blog.csdn.net/mazhimazh/article/details/19291965

转载于:https://www.cnblogs.com/lddbupt/p/5758955.html

相关文章:

  • TYVJ P1020 寻找质因数
  • 疯狂ios讲义之使用CoreLocation定位(4)
  • 前进的方向不一定都是对的,但是探索本身无法改变
  • TCP拥塞控制
  • JS 下拉菜单
  • usr/bin/ld: cannot find -lxxx
  • 学会给予
  • JSP中的九大内置对象和四大作用域
  • Mysql 大数据量导入程序
  • 配置RD网关实现直接访问内网
  • ASP.NET配合CKEditor上传图片(二)
  • 导航状态尺寸
  • ubuntu下启动system-config-kickstart报错的解决办法
  • iOS - Swift NSPoint 位置
  • Zabbix自定义监控详解
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • 实现windows 窗体的自己画,网上摘抄的,学习了
  • ES6简单总结(搭配简单的讲解和小案例)
  • HTML-表单
  • iOS小技巧之UIImagePickerController实现头像选择
  • JS 面试题总结
  • Laravel 实践之路: 数据库迁移与数据填充
  • Linux各目录及每个目录的详细介绍
  • SpiderData 2019年2月13日 DApp数据排行榜
  • UMLCHINA 首席专家潘加宇鼎力推荐
  • 海量大数据大屏分析展示一步到位:DataWorks数据服务+MaxCompute Lightning对接DataV最佳实践...
  • 基于Android乐音识别(2)
  • 力扣(LeetCode)357
  • 力扣(LeetCode)965
  • 猫头鹰的深夜翻译:JDK9 NotNullOrElse方法
  • 如何进阶一名有竞争力的程序员?
  • 通过npm或yarn自动生成vue组件
  • 线性表及其算法(java实现)
  • 用简单代码看卷积组块发展
  • 中文输入法与React文本输入框的问题与解决方案
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • HanLP分词命名实体提取详解
  • ​一些不规范的GTID使用场景
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (30)数组元素和与数字和的绝对差
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第2节(共同的基类)
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (TOJ2804)Even? Odd?
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (三)Honghu Cloud云架构一定时调度平台
  • (五)大数据实战——使用模板虚拟机实现hadoop集群虚拟机克隆及网络相关配置
  • (译)计算距离、方位和更多经纬度之间的点
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .htaccess 强制https 单独排除某个目录
  • .Net - 类的介绍
  • .NET Core 通过 Ef Core 操作 Mysql
  • .net 使用$.ajax实现从前台调用后台方法(包含静态方法和非静态方法调用)
  • .NET 中使用 TaskCompletionSource 作为线程同步互斥或异步操作的事件
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)