Java 中的线程池 ThreadPool

线程池主要有以下三种:

SingleThreadExecutor
FixedThreadPool
CachedThreadPool

SingleThreadExecutor

只有一个线程的线程池, 核心线程数为 1, 最大线程数为 1,线程存活时间 0(反正也用不到…),阻塞队列使用的 LinkedBlockingQueue(一个 FIFO 队列)

这里写图片描述


FixedThreadPool

线程数与核心线程数相同,在构造时指定,线程存活时间 0(反正也用不到…),阻塞队列使用的 LinkedBlockingQueue(一个 FIFO 队列)

这里写图片描述


CachedThreadPool

核心线程数 0, 最大线程数 2^31 -1 , 存活时间 60s,阻塞队列使用的是 SynchronousQueue(不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则移除操作一直处于阻塞状态;通常吞吐量高于 LinkedBlockingQueue)

这里写图片描述


通过观察可以看出,他们仨都调用了这个玩意

这里写图片描述

核心线程数,当线程池中线程数量小于此数值时,存活时间不会生效,即使线程一直闲置(idle),也不会 go die

最大线程数,线程池中允许存在的最大线程数量

存活时间,当线程池中线程数量超过核心线程数,如果有线程处于 idle 状态,超过此 存活时间,就会 狗带

时间单位,通常使用 秒 seconds

阻塞队列,当调用 execute 或者 submit 提交(执行)任务时,如果核心线程数已满,阻塞队列未满,则将 task 丢到阻塞队列中

阻塞队列主要有四种选择:

  • ArrayBlockingQueue 基于数组的阻塞队列

  • LinkedBlockingQueue 基于链表的阻塞队列

  • SynchronousQueue 不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态

  • PriorityBlockingQueue 具有优先级的无限阻塞队列


RejectedExecutionHandler 拒绝策略,当 阻塞队列,线程池(线程池中线程达到最大线程数时)都满了,将会采取的策略

  • AbortPolicy 直接抛出异常

  • CallerRunsPolicy 只用调用者所在线程来运行任务

  • DiscardOldersPolicy 丢弃队列里最近的一个任务,并执行当前任务

  • DiscardPolicy 不处理,直接丢掉


execute() 方法的执行过程:


合理配置线程池:

1、CPU 密集型任务,配置 N(CPU数量)+1 个线程数

2、IO 密集型任务,配置 2N + 1 个线程数

加一的原因:

即使当计算密集型的线程偶尔由于缺失故障或者其他原因而暂停时,这个额外的线程也能确保CPU的时钟周期不会被浪费。


参考资料:

1。《Java 并发编程艺术》

2、Java并发核心基础——线程池使用及底层实现机制详解
https://blog.csdn.net/zhangliangzi/article/details/52389766

3、java线程池大小为何会大多被设置成CPU核心数+1?
https://www.zhihu.com/question/38128980

4、Java几种线程池的分析和使用
https://zhuanlan.zhihu.com/p/22882522


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值