1

從EDT(Event Dispatcher Thread)啓動新線程時,新線程永遠不會是EDT,因爲只有一個EDT,對嗎?我問,因爲我看到一些代碼檢查if (!SwingUtils.isDispatcherThread()),我不知道爲什麼需要這個檢查?EDT,異步,同步

我的問題是:什麼時候啓動一個新線程,它是同步的(必須等待新線程完成)還是異步(新線程立即返回)?相應的如何啓動一個同步或異步的線程?

以下列爲例。在EDT中啓動非EDT線程時,如下所示:

public void actionPerformed(final ActionEvent e) 
{ 
    final Runnable runnable = new Runnable() 
    { 
     @Override 
     public void run() 
     { 
     //do some non-gui task. The task is not long-running, but 
     //could be blocked 
     doTask();  
     } 
    }; 

    new Thread(runnable).start(); 
    } 
}); 

非EDT線程是從EDT產生的同步還是異步?如果doTask()掛起,EDT UI應該被阻止?

如果我無法控制doTask()並且該方法無法更改,那麼處理產生新線程和新線程可能會掛起的情況的好方法是什麼?在父線程中使用Thread.join()

回答

2

新線程永遠不會是EDT,因爲只有一個EDT,對嗎?

沒錯。

我在問,因爲我看到一些代碼檢查「if(!SwingUtils.isDispatcherThread())」,我想知道爲什麼需要這個檢查?

因爲有時可以從EDT或後臺線程調用方法,並且必須根據當前線程採取不同的操作。

開始一個新的線程的時候,是什麼使得它同步的(必須等待新的線程來完成)或異步的(新的線程立即返回)?

當你開始一個新的線程時,新線程總是同時運行到產卵線程。除非你明確地加入(或使用另一種同步機制),否則產卵線程永遠不會等待產生的線程完成。

如果doTask()掛起,EDT UI應該被阻塞嗎?

不,例如,除非產生的線程掛起,同時保持EDT嘗試獲取的鎖定。

如果我無法控制doTask()並且方法無法更改,那麼處理產生新線程和新線程可能會掛起的情況的好方法是什麼?在父線程中使用Thread.join()?

這會更糟糕:現在EDT也會掛起,從而完全凍結UI,直到掛起的線程停止掛起並終止。

如果你有一個掛起的線程,然後修復它正在執行的代碼,以便它不再掛起。如果您無法解決問題,請向負責該代碼的人員解決問題。

+0

謝謝!只想確認: – user3014901

+0

謝謝!只是想確認一下:(1)你的意思是一個新的Thread.start()默認情況下總是立即返回父線程?或者它取決於?通過併發,你的意思是父線程和新線程有相同的機會被安排運行,並且它們被隨機調度運行? (2)我的期望是如果產卵的非EDT線程掛起,EDT線程就會運行。這不可行嗎? – user3014901

+0

1.是的。是的。 2.如果任何其他線程掛起,EDT線程將繼續運行。他們同時運行。 –

0
  1. EDT:是的,只有1 EDT。你做不會是EDT
  2. 同步和一步的任何線程:Thread在Java中像任何其他一類,但是當你調用start()它創建運行無論在run()方法或在Runnable.run方法是一個新的線程如果Runnable是異步提供的。
  3. 方法可能會阻塞/永不返回:關鍵是要使用回調/偵聽器...在導致更新的處理中的某個點被調用的方法。沒有通用的解決方案來停止被阻塞的線程,但是在很多情況下可以工作的兩種機制是(a)如果您正在等待輸入流或閱讀器上的數據,或者(b)線程,則爲InputStream/Reader.close()。中斷
+0

謝謝你的回覆。掛線需要睡覺()才能被打斷,對嗎? – user3014901