线程池在接受到30个比较耗时的任务时的状态,在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?

目录

一、提出问题

二、解答

问题 1: 线程池在接受到30个比较耗时的任务时的状态

问题 2: 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?

总结


一、提出问题

我们首先自定义一个线程池:

new ThreadPoolExecutor(10,
      30,
      60,
      TimeUnit.SECONDS,
      new LinkedBlockingQueue<>(1000),
      new NamedthreadFactory("myPool"));

拿着这个线程池,当这个线程池在正常工作的前提下,问两个问题:

  1. 如果这个线程池接受到了30个比较耗时的任务,这个时候线程池的 状态(或者说数据)是怎样的?
  2. 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任 务会触发拒绝策略?

二、解答

问题 1: 线程池在接受到30个比较耗时的任务时的状态

我们先看第一个问题,在接受到30个比较耗时的任务时,线程池的状态如下:

  1. 核心线程数 (corePoolSize):10
    首先,线程池会启动10个核心线程来处理前10个任务。这些任务会立即开始执行。

  2. 任务队列 (workQueue):1000
    在核心线程已经全部被占用的情况下,剩下的任务(第11个到第30个)会被放入工作队列中。这些任务会等待直到有线程空闲。

  3. 最大线程数 (maximumPoolSize):30
    因为任务队列尚未达到其容量上限,所以线程池不会再创建新的线程来处理任务。也就是说,线程池中的线程数仍保持在10个。

  4. 线程池状态

    • 线程数:10个线程正在运行。
    • 工作队列:工作队列中有20个任务在等待执行。
    • 队列大小:队列中剩余可用空间为980(1000 - 20)。

因此,线程池在接受到30个耗时任务时,10个任务正在执行,20个任务在队列中等待。

问题 2: 在前面30个比较耗时的任务还没执行完成的情况下,再来多少个任务会触发拒绝策略?

在前面30个比较耗时的任务还没执行完成的情况下:

  1. 工作队列 (workQueue)

    • 当前工作队列中已经有20个任务在等待,还有980个空位。
  2. 最大线程数 (maximumPoolSize):30

    • 线程池已经启动了10个核心线程,所有核心线程都在忙碌。
    • 工作队列还没有填满(容量是1000)。

因此,在此时再提交980个任务,这些任务将会被放入队列而不会触发拒绝策略。

第981个任务:当第981个任务被提交时,队列已经满了。此时,线程池将会创建新的线程来处理任务,因为还未达到最大线程数。线程池最多可以创建20个额外的线程(从10个到最大30个),这些线程会立即处理新提交的任务。

触发拒绝策略的条件:如果再提交任务使得线程池中的线程数达到了最大线程数(30个),且任务队列已满(1000个任务在等待),那么再提交第1001个任务时,就会触发拒绝策略。

总结

触发拒绝策略前:前面30个耗时任务已占据了所有核心线程和部分工作队列,队列还有980个空位。因此,接下来的980个任务可以被接受,而不会触发拒绝策略。

触发拒绝策略时:再提交的任务数使得队列满且线程数达到最大值(30个),此时再提交的任务(第1001个任务)会触发拒绝策略。

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
线程池中,如果想要取消一个任务,可以使用`Future`对象的`cancel()`方法来实现。`Future`对象代表了一个异步任务的结果,可以用来检查任务是否已经完成,以及获取任务执行结果。 首先,当你提交一个任务线程池返回一个`Future`对象,通过这个对象可以操作该任务。要取消任务,你可以调用`Future`对象的`cancel()`方法,并传入一个布尔值参数来指定是否通过中断来取消任务。 如果任务尚未开始执行,那么任务将被标记为已取消,并且不执行。如果任务已经在执行中,那么取决于你传入的布尔值参数: - 如果布尔值参数为`true`,那么任务将被中断(如果线程支持中断操作)。这意味着线程抛出一个`InterruptedException`异常。 - 如果布尔值参数为`false`,那么任务将不被中断,但是`cancel()`方法返回`false`。 需要注意的是,`cancel()`方法只是尝试取消任务,但无法保证一定成功。如果任务已经在执行过程中,那么它可能无法被取消。 以下是一个示例代码片段,演示如何使用线程池和`Future`对象取消任务: ```java import java.util.concurrent.*; public class ThreadPoolExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(1); // 提交任务线程池 Future<?> future = executor.submit(() -> { // 执行耗时任务 // ... // 检查任务是否被取消 if (Thread.currentThread().isInterrupted()) { // 任务被取消,提前退出 return; } // 继续执行任务 // ... }); // 取消任务 boolean cancelled = future.cancel(true); if (cancelled) { System.out.println("任务取消成功"); } else { System.out.println("任务取消失败"); } // 关闭线程池 executor.shutdown(); } } ``` 在上述示例中,我们创建了一个固定大小为1的线程池,并提交了一个任务。然后,我们调用`Future`对象的`cancel()`方法来取消任务,并打印出取消结果。最后,我们关闭了线程池。 请注意,取消任务只是一种尝试,具体是否成功还取决于任务的具体实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水w

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

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

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

打赏作者

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

抵扣说明:

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

余额充值