我有一個簡單的計時器,每分鐘都會調用一個方法來進行後臺處理。它被稱爲是這樣的:Java定時器如何在脅迫下執行?
EmailSender singletonSender = new EmailSender(cog);
timer.scheduleAtFixedRate(singletonSender, 60000, 60000);
它接收到一個事件,檢查,看看是否有任何理由發送電子郵件每一分鐘,發送電子郵件,然後它完成。
這一切都假定系統已啓動並正在運行,並且有可用的CPU週期。如果計算機坐在那裏什麼也不做,而且處理沒有時間,這一切都很容易理解。但是當計算機過於忙碌或處於睡眠/睡眠模式時,我找不到有關這種行爲的文檔。
如果電腦睡着了會發生什麼?
經過檢查了許多令人困惑的日誌後,我終於進行了測試。打印出日誌聲明和當前時間。我把電腦在7點30分左右睡着了,大約10分鐘後把它喚醒了。這裏是日誌跟蹤:
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:24:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:25:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:26:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:27:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:28:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:29:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:30:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:31:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:09
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:40:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:41:28
BACKGROUND EVENTS: Processed 0 background events at Fri Nov 06 07:42:28
這似乎發出一串「追趕」事件。換句話說,就好像它們在睡着時一直堆放在電腦中,然後一旦機器重新啓動後它們全部涌出。就好像所有的事件都是由事件產生的,但由於無法提供它們而受到阻礙,最後,當計算機啓動時,所有事件都會氾濫。
這是按照這種方式設計的嗎?顯然,這對您設計系統的方式有影響。 IT是合乎邏輯的,如果你預計每天1440個事件,你最終將獲得1440個事件。但是,如果您只是在進行後臺處理,並且每個調用都會完成所有等待的後臺工作,那麼這些額外的調用就會毫無意義。您將需要設計方法來快速處理這些額外的大量呼叫。
如果回覆通話需要一分多鐘的時間會怎麼樣?
鑑於上述證據,看起來如果電腦變得非常忙碌,可能是您的活動遲到,但您仍然可以獲得所有活動。所以如果一個事件的處理需要一分多鐘的時間,問題是:你能確定事件不會到達另一個線程嗎?換句話說:你確信你的處理程序永遠不會在最後一次調用完成之前被調用。 Timer機制試圖隱藏你被調用的線程的細節,假設所有的調用都是在單個線程上進行似乎是合理的,但是,我正在尋找明確的文檔。
我在想什麼:這是嚴格定義的一些地方?或者僅僅是當前版本實施方式的人爲因素?
您可能想嘗試[ScheduledExecutorService的(https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ScheduledExecutorService.html),看看它的行爲相同。 scheduleAtFixedRate的替代方法是在每次運行結束時安排新的運行。 – assylias