Java多线程 - 线程池的任务调度流程?

本文详细解析了Java线程池的工作原理,包括启动策略、任务调度流程及拒绝策略。当线程池队列已满且达到最大线程数时,将触发拒绝策略。合理的线程池配置至关重要,否则可能导致任务调度问题,如严重的排队等待。配置不当可能影响并发执行,加剧延迟。理解这些原理有助于优化线程池性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题:

1、线程池的启动策略?
2、线程池的任务调度流程?
3、线程池的工作原理?
4、如果你提交任务时,线程池队列已满,这时会发生什么?

/**
 * 使用标准构造器构造一个普通的线程池
 *
 * @param corePoolSize  核心线程数,即使线程空闲,也不会回收
 * @param maximumPoolSize  线程数的上限(最大线程数)
 * @param keepAliveTime  线程最大空闲时间(线程的生存时间)
 * @param unit 时间单位
 * @param workQueue 任务的排队队列
 * @param threadFactory 新线程的产生方式
 * @param handler 拒绝策略
 */
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler)

线程池的任务调度流程大致如下:

(1)如果当前工作线程数量小于核心线程数量,执行器总是优先创建一个任务线程,而不是从线程队列中获取一个空闲线程。

(2)如果线程池中总的任务数量大于核心线程池数量,新接收的任务将被加入阻塞队列中,一直到阻塞队列已满。在核心线程池数量已经用完、阻塞队列没有满的场景下,线程池不会为新任务创建一个新线程。

(3)当完成一个任务的执行时,执行器总是优先从阻塞队列中获取下一个任务,并开始执行,一直到阻塞队列为空,其中所有的缓存任务被取光。

(4)在核心线程池数量已经用完、阻塞队列也已经满了的场景下,如果线程池接收到新的任务,将会为新任务创建一个线程(非核心线程),并且立即开始执行新任务。

(5)在核心线程都用完、阻塞队列已满的情况下,一直会创建新线程去执行新任务,直到池内的线程总数超出maximumPoolSize。如果线程池的线程总数超过maximumPoolSize,线程池就会拒绝接收任务,当新任务过来时,会为新任务执行拒绝策略。
在这里插入图片描述
在创建线程池时,如果线程池的参数(如核心线程数量、最大线程数量、BlockingQueue等)配置得不合理,就会出现任务不能被正常调度的问题。

比如corePoolSize为1,阻塞队列的大小为100,按照线程创建的规则,需要等阻塞队列已满,才会去创建新的线程。假如加入了5个任务,阻塞队列大小为4(<100),所以线程池的调度器不会去创建新的线程,后面的4个任务只能等待。

(1)核心和最大线程数量、BlockingQueue队列等参数如果配置得不合理,可能会造成异步任务得不到预期的并发执行,造成严重的排队等待现象。

(2)线程池的调度器创建线程的一条重要的规则是:在corePoolSize已满之后,还需要等阻塞队列已满,才会去创建新的线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我一直在流浪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值