簡體   English   中英

如何正確關閉 ScheduledExecutorService

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM