2010-05-10 53 views
1

有沒有更好的方法來做我在下面做的事情?也就是說,是否有比投票和睡眠,投票和睡眠更優雅的方式,以便知道何時通過invokeLater()調用了Runnable.run()方法?等待invokeLater()被調用

private int myMethod() { 
    final WaitForEventQueue waitForQueue = new WaitForEventQueue(); 
    EventQueue.invokeLater(waitForQueue); 
    while (!waitForQueue.done) { 
     try { 
      Thread.sleep(10); 
     } catch (InterruptedException ignore) { 
     } 
    } 

    return 0; 
} 

private class WaitForEventQueue implements Runnable { 
    private boolean done; 

    public void run() { 
     // Let all Swing text stuff finish. 
     done = true; 
    } 
} 
+0

對於任何值得的代碼,這個代碼在兩個層次上失敗:(1)它不是線程安全的,因爲等待線程可能永遠不會「看到」更新到'done'(參見Java Memory Model for V5 +)和2)輪詢通常是一個不好的解決方案,特別是在具有這種簡單的等待/通知機制的語言中(見Object.wait等)。 – 2010-05-10 19:15:23

回答

2

如果你想等待,爲什麼不打電話invokeAndWait而不是自己實施它?

+0

因爲invokeAndWait導致死鎖和活鎖,並基本上吃早餐的小貓。 – Trejkaz 2014-03-21 02:13:16

+0

@Trejkaz,不是我的經驗,但我確信建議的代碼不會有所改進。 – Yishai 2014-03-21 02:27:21

+0

可能不是,雖然我很好奇。因爲它沒有使用鎖,所以它可能不會死鎖。不過,我認爲它會出現這個問題,它不會死鎖,但永遠不會返回。 – Trejkaz 2014-03-21 02:38:11

0

而不是等待線程完成,爲什麼不只是讓用戶界面顯示一個微調或什麼,並讓線程在完成時調用一個事件。

+0

嗨,賈斯汀, 感謝您的建議,但你可以更具體(即顯示一些示例代碼),只要「線程調用一個事件,當它完成」的一部分? – 2010-05-10 18:40:27

5

更好的方法是使用FutureTask(實現Runnable和Future)並覆蓋它的done()事件來完成某些操作。

另外,如果它不是在執行GUI操作,而是使用AWT EventQueue,則將其作爲單獨的線程啓動(或使用Executor)。