2011-10-18 109 views
4

我對Java比較陌生,對ActionListeners的工作方式感到好奇。說我對爲實現定時器動作監聽器如下:如果定時器設置爲我的ActionListener類可以執行運行比代碼快Java中的Timer ActionListener操作

class TimerActionListener implements ActionListener 
{ 
    public void actionPerformed(ActionEvent e) 
    { 
     //perform some operation 
    } 
} 

會發生什麼。代碼是否完成執行,並在完成之前忽略新請求(如中斷)。或者,對動作偵聽器的新調用優先於當前實例 - 這樣代碼永遠不會完成?

回答

8

計時器的定時在線程從事件調度線程(或EDT)不同完成其是運行在的ActionListener的代碼的線程。因此,即使actionPerformed代碼很慢,計時器也會持續啓動,並且會將其actionPerformed代碼排隊在事件隊列上,事件隊列可能會被備份,並且事件線程將被阻塞,應用程序將無響應或響應不佳。

帶回家的一點是要避免調用是需要一點時間的事件線程上,因爲它會使GUI反應遲鈍的任何代碼。考慮使用SwingWorker來處理這種情況。

編輯:請參閱下面的垃圾評論的勝利!

+0

如果是這樣的話,有沒有什麼辦法讓它下降,而不是排隊到ActionListener的新要求? – Ben

+0

@Ben:一個很好的問題,我不知道答案。我猜測是的,有一種方法,但也可能會在美國東部時間之前完成。 –

+7

請參閱['setCoalesce()'](http://download.oracle.com/javase/7/docs/api/javax/swing/Timer.html#setCoalesce%28boolean%29)。 – trashgod

2

您可以測試它自己實現的東西如下:

class TimerActionListener implements ActionListener { 
    public static int inst = 1; 
    public void actionPerformed(ActionEvent e) { 
     int id = inst++; 
     System.out.println("Executing instance: " + id); 
     try { Thread.sleep(3000); } catch (Exception e) {} //For sleep 3 seconds 
     System.out.println("Instance: " + id + "done! "); 
    } 
} 
+0

運行您的代碼似乎意味着額外的請求會被刪除,因爲id總是匹配。然而,它也可以按照Hovercraft的建議排隊。由於代碼僅打印文本,因此難以判斷是否因此導致性能下降。 – Ben

3

基於從氣墊船和trashgod的職位,似乎定時器事件不被其默認設置隊列。 (直到計時器事件處理程序代碼執行完畢,即新的計時器事件將被忽略。)

+0

'1)'我知道聲譽<50的用戶可以發表評論,那麼最好是編輯你的帖子,'2)'請問你在說什麼,no_code no_hash – mKorbel

+0

我不太確定我明白你的意思意思是,但要澄清,這篇文章的目的是回答我自己的問題,因爲它沒有明確說明(雖然信貸確實去氣墊船/ trashgod指向我在正確的方向)。 – Ben