[英]How to correctly shutdown ScheduledExecutorService
我仍在努力了解如何使用 ScheduledExecutorService。 我想要一個 ScheduledExecutorService/ScheduledThreadPoolExecutor,它可以調度多個任務並讓它們運行固定的次數。 一旦不再安排任務,我想關閉 ScheduledThreadPoolExecutor。 我試圖通過編寫一些測試來了解這如何工作。 我嘗試的第一件事是:
@Test
public void testExecutorService() throws Exception {
ScheduledThreadPoolExecutor executorService = new ScheduledThreadPoolExecutor(1);
executorService.setRemoveOnCancelPolicy(true);
CountDownLatch latchOne = new CountDownLatch(5);
CountDownLatch latchTwo = new CountDownLatch(10);
ScheduledFuture<?> scheduledFutureOne = executorService.scheduleAtFixedRate(new MyRunnerOne(latchOne), 0, 1, TimeUnit.SECONDS);
ScheduledFuture<?> scheduledFutureTwo = executorService.scheduleAtFixedRate(new MyRunnerTwo(latchTwo), 0, 2, TimeUnit.SECONDS);
latchOne.await();
scheduledFutureOne.cancel(false);
latchTwo.await();
scheduledFutureTwo.cancel(false);
System.out.println("Shutting down service...");
executorService.shutdown();
Thread.sleep(100);
assertTrue(executorService.isTerminated());
}
class MyRunnerOne implements Runnable
{
CountDownLatch latch;
MyRunnerOne(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
System.out.println("Do Task One : " + latch.getCount());
latch.countDown();
}
}
class MyRunnerTwo implements Runnable
{
CountDownLatch latch;
MyRunnerTwo(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
System.out.println("Do Task Two: " + latch.getCount());
latch.countDown();
}
}
這很好用,我得到了預期的 output:
Do Task One : 5
Do Task Two: 10
Do Task One : 4
Do Task One : 3
Do Task Two: 9
Do Task One : 2
Do Task One : 1
Do Task Two: 8
Do Task Two: 7
Do Task Two: 6
Do Task Two: 5
Do Task Two: 4
Do Task Two: 3
Do Task Two: 2
Do Task Two: 1
Shutting down service...
但是,我這僅有效,因為我在等待latchTwo 之前等待latchOne,因為第一個任務花費的時間更少。 如果我切換這個順序,即
latchTwo.await();
scheduledFutureTwo.cancel(false);
latchOne.await();
scheduledFutureOne.cancel(false);
任務一將被進一步執行,即使鎖存器已達到零,因為它僅在任務二之后被取消。 有沒有辦法在鎖存器為零時立即執行某些操作(在這種情況下為 scheduledFutureOne.cancel(false) )並且一次對多個鎖存器執行此操作?
我還嘗試按照此答案中描述的設置再次運行良好,但我不知道在哪里/如何關閉 ExecutorService。 設置類似,增加原子 integer 直到達到所需的調用次數,然后我們取消未來。 不過,這仍然不會關閉 ExecutorService。
TLDR 我想用一個 ExecutorService 安排多個任務,每個任務都有固定數量的調用。 ExecutorService 處理任務的順序應該允許是隨機的。 一旦不再安排任何任務,ExecutorService 就應該關閉。
謝謝你們的任何想法:)
如果您讓任務在執行器服務中重新安排自己,這樣做會更容易:
ScheduledThreadPoolExecutor executorService = new ScheduledThreadPoolExecutor(1);
CountDownLatch latchOne = new CountDownLatch(1);
CountDownLatch latchTwo = new CountDownLatch(1);
executorService.submit(new MyRunnerOne(executorService, latchOne, 5));
executorService.submit(new MyRunnerTwo(executorService, latchTwo, 10));
latchTwo.await();
latchOne.await();
System.out.println("Shutting down service...");
executorService.shutdown();
executorService.awaitTermination(100, TimeUnit.SECONDS);
System.out.println("Terminated: " + executorService.isTerminated());
//...
class MyRunnerOne implements Runnable {
private final ExecutorService service;
private final CountDownLatch latch;
private final int count;
MyRunnerOne(ExecutorService service, CountDownLatch latch, int count) {
this.service = service;
this.latch = latch;
this.count = count;
}
@Override
public void run() {
System.out.println("Do Task One : " + count);
if (count > 1) {
service.submit(new MyRunnerOne(service, latch, count - 1));
} else {
latch.countDown();
}
}
}
完整代碼。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.