4

我正在玩ScheduledExecutorService。我想要做的是開始一個簡單的代碼(每秒一個tick),並在稍後(五秒鐘後)安排另一個任務,取消第一個任務。然後阻止主線程直到所有內容完成,這應該在兩個任務完成後(+ - 五秒)完成。如何從其他任務取消ScheduledFuture任務並正常結束?

這是我的代碼:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 
Runnable tickTask =() -> System.out.println("Tick"); 
ScheduledFuture<?> scheduledTickTask = executor.scheduleAtFixedRate(tickTask, 0, 1, TimeUnit.SECONDS); 
Runnable cancelTask =() -> scheduledTickTask.cancel(true); 
executor.schedule(cancelTask, 5, TimeUnit.SECONDS); 
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 

這suprises我的問題是,它會阻止彷彿仍有一些正在運行的任務。爲什麼? cancelTask應該立即結束,scheduledTickTask剛剛取消,那麼問題是什麼?

回答

5

按照ExecutorService.awaitTermination(重點煤礦)的Javadoc中:

阻塞,直到所有任務完成執行關機請求後,或發生超時或者當前線程被中斷,先發生者爲準。

這意味着你首先需要調用shutdown,像這樣:

ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(); 
Runnable tickTask =() -> System.out.println("Tick"); 
ScheduledFuture<?> scheduledTickTask = executor.scheduleAtFixedRate(tickTask, 0, 1, TimeUnit.SECONDS); 
Runnable cancelTask =() -> { 
    scheduledTickTask.cancel(true); 
    executor.shutdown(); 
}; 
executor.schedule(cancelTask, 5, TimeUnit.SECONDS); 
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 

在你的情況,超時將永遠不會發生,因爲實際上你將其設置爲「無限」,並且當前線程不中斷。

+0

感謝您的回答,這是Javadoc中一個簡單的筆記,我錯過了。有沒有辦法自動取消最後一項任務後如何關閉調度程序?或者你將不得不在某個地方保留一個櫃檯並在它等於零後關閉? – voho

+0

@voho我不知道這是否可以使用'ScheduledExecutorService'。看看[這個問題](http://stackoverflow.com/q/23369952/1743880)。 – Tunaki