2017-05-24 56 views
0

這是代碼:爲什麼ScheduledExecutorService在15秒內關閉,但它仍然會執行第17和第20秒任務?

public class TimerTask { 
    private final ScheduledExecutorService scheduler; 
    private ScheduledFuture<?> scheduledFuture; 

    TimerTask() { 
    scheduler = Executors.newScheduledThreadPool(1); 
    } 

    private void startTimerTask() { 
    Runnable printTask = createPrintTask(); 
    System.out.println(new Date()); 
    scheduledFuture = scheduler.scheduleAtFixedRate(printTask, 5, 2, TimeUnit.SECONDS); 
    scheduler.schedule(() -> { 
     if (scheduledFuture != null && !scheduledFuture.isCancelled()) { 
     scheduledFuture.cancel(true); 
     System.out.println(new Date()); 
     } 
    }, 10, TimeUnit.SECONDS); 

    scheduler.schedule(() -> { 
     if (scheduledFuture != null || scheduledFuture.isCancelled()) { 
     System.out.println(scheduledFuture.isDone() + " " + scheduledFuture.isCancelled()); 
     scheduler.shutdown(); 
     } 
    }, 15, TimeUnit.SECONDS); 

    scheduler.schedule(() -> { 
     if (scheduledFuture != null || scheduledFuture.isCancelled()) { 
     System.out.println("danluo"); 
     } 
    }, 17, TimeUnit.SECONDS); 

    scheduledFuture = scheduler.scheduleAtFixedRate(printTask, 20, 2, TimeUnit.SECONDS); 
    } 

    private Runnable createPrintTask() { 
    return() -> System.out.println("nsnnsn" + new Date()); 
    } 

    public static void main(String []args) { 
    TimerTask timerTask = new TimerTask(); 
    timerTask.startTimerTask(); 
    } 

} 

這是輸出:

Wed May 24 10:39:06 CST 2017 
nsnnsnWed May 24 10:39:11 CST 2017 
nsnnsnWed May 24 10:39:13 CST 2017 
nsnnsnWed May 24 10:39:15 CST 2017 
Wed May 24 10:39:16 CST 2017 
nsnnsnWed May 24 10:39:17 CST 2017 
nsnnsnWed May 24 10:39:19 CST 2017 
nsnnsnWed May 24 10:39:21 CST 2017 
true true 
danluo 

爲什麼它會前17秒和15秒20執行第二個任務? 看起來很奇怪。你能幫我回答這個問題嗎? 謝謝。

它表明代碼太多了,我不知道爲什麼,所以我再補充一些解釋。

回答

0

當你說,

scheduler.schedule(() -> { 
    if (scheduledFuture != null || scheduledFuture.isCancelled()) { 
    System.out.println("danluo"); 
    } 
}, 17, TimeUnit.SECONDS); 

你可以像讀它,如果scheduledFuture不是null它已經被取消這是沒有邏輯意義。如果是null那麼第二個測試會拋出一個空指針異常。因此,我只能斷定你想

scheduler.schedule(() -> { 
    if (scheduledFuture != null && !scheduledFuture.isCancelled()) { 
    System.out.println("danluo"); 
    } 
}, 17, TimeUnit.SECONDS); 

其內容

如果scheduledFuturenull沒有被取消。

因爲當你已經結束了,你大概想繼續做任務的任務。至於第二個scheduledFuture在20秒的間隔,當你說scheduledFuture = scheduler.scheduleAtFixedRate你創建一個新的...... jvm指出,你不再引用舊的scheduledFuture實例 - 但你有更多的一個,並且一個不是可達(給你)。爲此使用新的參考名稱。或者如果您需要安排多個任務,請撥打List或使用PriorityQueue

+0

是的,非常感謝,我已經明白了。 – danny

0

從爲什麼計劃任務雖然ExecutorService的執行你的文章的標題回答的問題是,從JavaDoc中關機ExecutorService.shutdown()

發起在以前已提交任務的執行有序關閉,但是不新任務將被接受。如果已關閉,調用沒有其他影響。

所以你的計劃任務將運行,直到他們完成,只有然後ExecutorService本身將停止。

相關問題