我有一段代码
public static void main(String[] args){
ScheduledThreadPoolExecutor stpe = new ScheduledThreadPoolExecutor(5);
AtomicInteger i = new AtomicInteger(0);
Runnable runnable = () -> {
if(i.get() < 5){
try{ Thread.sleep(2_000); }catch(Exception ignored){ }
}else if(i.get() >= 15){
System.exit(0);
}
System.out.println(i.getAndIncrement() + " - " + stpe.getQueue().size() + " - " + LocalDateTime.now());
};
ScheduledFuture<?> sf = stpe.scheduleAtFixedRate(new Thread(runnable, "Testing"), 0, 1_000, TimeUnit.MILLISECONDS);
}
执行后的控制台:
0 - 0 - 2023-03-27T13:40:04.865501800
1 - 0 - 2023-03-27T13:40:06.886657500
2 - 0 - 2023-03-27T13:40:08.890066
3 - 0 - 2023-03-27T13:40:10.894186200
4 - 0 - 2023-03-27T13:40:12.898171
5 - 0 - 2023-03-27T13:40:12.899077100 <---
6 - 0 - 2023-03-27T13:40:12.899077100 <---
7 - 0 - 2023-03-27T13:40:12.900068700 <---
8 - 0 - 2023-03-27T13:40:12.900068700 <---
9 - 0 - 2023-03-27T13:40:12.900068700 <---
10 - 0 - 2023-03-27T13:40:12.901073800 <---
11 - 0 - 2023-03-27T13:40:13.857069500
12 - 0 - 2023-03-27T13:40:14.852331500
13 - 0 - 2023-03-27T13:40:15.860971200
14 - 0 - 2023-03-27T13:40:16.865873300
正如你所看到的,我有一个Thred.sleep(2_000)
用于前5次执行,之后我让它们以ScheduledFuture的速度执行,直到第15次执行,这将停止程序。
我知道scheduleAtFixedRate
在当前执行完成之前不会开始新的执行。
但相反,是在等待队列中添加它们,从那里是采取一个接一个,并执行不尊重率.
正如你所看到的,从5到10,和4一样在同一秒。执行5-10在等待队列中,一个接一个地执行,没有速率。它们之间的差异,作为时间,只是执行时间。
在等待队列被释放后,它以这个速度从11点持续到14点。
我如何才能避免5-10个执行是一个接一个立即,而是以固定的速度(~1_000毫秒)执行?我可以找到这个等待队列,并释放它?
我希望task 0结束和task 1开始之间的时间是1 s- task0_execution_time(就像scheduledAtFixedRate一样),但不要有可以累积任务的等待队列。
例如:
1.启动task 1,执行时间为5s。
1.启动task 2而不暂停(1 s- 5s = -4s =〉即时启动)。
1.在1 s- task2_execution_time时启动task 3。
不要将task 2和task 3累积在等待队列中并在稍后立即执行它们,因为task 1的执行时间为5s,而task 2和task 3计划在这5s期间启动
1条答案
按热度按时间wgmfuz8q1#
我根本不会使用执行器。一个简单的for循环和一个变量
sleep
完全可以满足你的要求: