gpt4 book ai didi

java - 如果另一个计时器事件挂起,ScheduledThreadPoolExecutor 计时器不会触发

转载 作者:行者123 更新时间:2023-12-01 21:18:38 25 4
gpt4 key购买 nike

考虑以下代码。

import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;


public class Test {
private static ScheduledThreadPoolExecutor threadPool = new ScheduledThreadPoolExecutor(0);

public static void onTimer() {
System.out.println("onTimer");
while (true) {
try {
Thread.sleep(1000);
} catch (InterruptedException ignored) {
}
}
}

public static void onTimer2() {
System.out.println("onTimer2");
}

public static void main(String[] args) {
threadPool.scheduleAtFixedRate(Test::onTimer, 0, 500, TimeUnit.MILLISECONDS);
threadPool.scheduleAtFixedRate(Test::onTimer2, 0, 500, TimeUnit.MILLISECONDS);
}
}

有两个以固定速率调度的计时器,并且在第一个计时器事件中,任务无限期挂起。

即使第一个任务挂起,我也希望第二个计时器以指定的速率触发,因为它是使用允许创建任意数量的线程的线程池创建的。

但是,第二个计时器永远不会触发。

谁能解释一下为什么吗?

最佳答案

引用自 ScheduledThreadPoolExecutor's javadoc我想解释一下

While this class inherits from ThreadPoolExecutor, a few of the inherited tuning methods are not useful for it. In particular, because it acts as a fixed-sized pool using corePoolSize threads and an unbounded queue, adjustments to maximumPoolSize have no useful effect. Additionally, it is almost never a good idea to set corePoolSize to zero or use allowCoreThreadTimeOut because this may leave the pool without threads to handle tasks once they become eligible to run.

您错过的关键部分是 ScheduledThreadPoolExecutor 类是“使用 corePoolSize 线程和无界队列的固定大小的池”。因此它不会产生任何超过 corePoolSize 的额外线程。

如果您想知道为什么它实际上以 corePoolSize == 0 执行,这里是来自 ThreadPoolExecutor 的代码片段,它确保至少有一个线程(以及防止在您的情况下启动更多线程的线程):

call order:  
1. java.util.concurrent.ScheduledThreadPoolExecutor#scheduleAtFixedRate
2. java.util.concurrent.ScheduledThreadPoolExecutor#delayedExecute
3. java.util.concurrent.ThreadPoolExecutor#ensurePrestart
/**
* Same as prestartCoreThread except arranges that at least one
* thread is started even if corePoolSize is 0.
*/
void ensurePrestart() {
int wc = workerCountOf(ctl.get());
if (wc < corePoolSize)
addWorker(null, true);
else if (wc == 0) //here's your case
addWorker(null, false);
}

关于java - 如果另一个计时器事件挂起,ScheduledThreadPoolExecutor 计时器不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39488344/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com