2010-08-10 27 views
3

所以我正在運行一個Java服務器,在一個類中我有一個靜態的Timer。然後我有另一個類,它有很多實例在程序的整個生命週期中被創建和銷燬,每個類都有自己的TimerTask(使用靜態Timer)。當一個實例被銷燬時,它會調用TimerTask上的cancel()。一個Java靜態定時器可以處理調用cancel()的多個TimerTasks嗎?

的問題是,我不知道這是很好的設計,並且還我得到的錯誤,有時,當實例被創建和調度其TimerTask的:

​​

下面是一些代碼來說明我的意思。

/** 
* Starts scheduled tasks using TimerTask 
*/ 
private void initTasks() 
{ 
    // room heartbeat thread: start immediately, run once every second 
    roomHeartbeatTask = new RoomHeartbeatTask(this); 
    RoomListExtension.roomHeartbeat.schedule(roomHeartbeatTask, 0, 1000); 
    // add additional tasks here 
} 

/** 
* Cancels all tasks that have been started by this extension 
*/ 
private void cancelTasks() 
{ 
    roomHeartbeatTask.cancel(); 
} 

回答

5

這個錯誤是因爲當你調用cancel()Timer是「死」,你不能做別的吧。

API

一旦計時器已經終止,它的執行線程終止優雅,並沒有更多的任務,可以在其上進行調度。

您有幾種選擇:

  1. 擺脫靜態Timer的,而是每個對象中持有的Timer一個單獨的實例。這樣當物體被摧毀時,您也可以銷燬Timer而不影響其他TimerTask。這將意味着每個對象有一個計時器線程。
  2. 保持靜態Timer,但也保存在內存中(例如在ArrayList<TimerTask>)其中的所有任務的列表。然後,當一個對象被銷燬時,您可以使用內存中的任務列表(減去與您創建的對象相對應的列表)重新創建靜態Timer對象。這樣做的結果是執行其餘的TimerTask可能需要一些安慰(特別是如果你不希望它們全部「聚集」)。
  3. 擴展或編寫自己的Timer-like類以允許刪除TimerTask s。 (有人可能已經這樣做了,我不知道)
  4. 使用一個ScheduledThreadPoolExecutor它允許您刪除任務。
+1

偉大的建議的選項!雖然澄清:即使我在TimerTask上調用cancel()而不是靜態Timer本身,計時器終止? – vazor 2010-08-10 19:27:59

+1

是的,我錯讀了。你應該可以取消TimerTask而沒有任何問題。如果你100%確定你的調用只針對TimerTask.cancel()而不是Timer.cancel(),那麼看看這裏:http://www.coderanch.com/t/452066/java/java/Exception -timer-IllegalStateException – Catchwa 2010-08-11 00:02:37

+0

ScheduledThreadPoolExecutor也解決了我的問題,謝謝! – yahya 2013-08-20 06:45:28

相關問題