我的混淆始于the api description的方法scheduleAtFixedRate。
如果此任务的执行时间超过其周期,那么 后续处决可能会延迟,但不会同时执行 执行。
如果没有并发执行,为什么还有一个线程池?
此外,有没有办法获得并发执行?我希望它们在确切的时间内运行,即使先前的任务还没有完成。我想要并发执行。
答案 0 :(得分:2)
文档应为:
..后续执行[提供的Runnable任务,每次注册] ..将不会同时执行
这并不意味着在所有计划任务中都不会有 no 并发。相反,对于每个任务(通过调用scheduleAtFixedRate
创建),Runnable一次只在一个线程上执行 - 如果执行时间超过间隔,则甚至。
这是一种明确的设计选择,因为在大多数情况下,任务回调的并发执行是不合需要的,并导致失控的资源螺旋。例如,如果同时执行越来越多的(相同的)Runnables,就会形成“任务炸弹”。
线程池monikor是准确的,因为实现执行它所宣传的操作 - 在任务执行中重用线程。
虽然没有标准的[Thread Pool] Executor具有所请求的行为,但它可以以有限的方式进行模拟。这是因为并发限制是每个已注册的任务(不是每个Runnable),并且可以注册多个“相同”任务:
long targetPeriod = ..;
long n = targetPeriod * 2;
task1 = executor.scheduleAtFixedRate(runnable, 0, n, ..)
task2 = executor.scheduleAtFixedRate(runnable, n/2, n, ..)
实际的执行/计时行为取决于各种其他因素,但是如果它们接管~n / 2(目标期间)以执行,则这两个注册的任务可以同时执行。
答案 1 :(得分:0)
有没有办法获得并发执行?我希望它们在确切的时间内运行,即使先前的任务还没有完成。我想要并发执行。
您可以从计划任务中启动(或提交给另一个执行程序)实际任务的另一个线程(假设该速率足够长以启动线程或提交任务)。如果任务持续时间超过您想要的速度,您最终可能会耗尽资源(如另一个答案中所述)。
例如:
ScheduledExecutorService ex = Executors.newScheduledThreadPool(1);
ex.scheduleAtFixedRate(() -> {
new Thread(() -> {
//do task
}).start();
}, 0, 1, TimeUnit.MINUTES);