我正在使用SwingWorker作爲一種方式來將非swing任務/動作與始終在Event Dispatch Thread中運行的Before和After方法一起包裝(換句話說:在之前調用doInBackground中的抽象方法之後再調用我在完成方法後調用)。由於無論在doInBackground中發生什麼,都必須進行同步,因此最近引發了很多麻煩。我注意到,如果我調用run而不是execute,問題就會消失,但是從我所瞭解的run方法與Thread中的方法相同,它只是從它被調用的完全相同的線程開始執行,而不是創建一個新的一個,因此doInBackground在EDT上執行時會在EDT上執行。我的想法是否正確?我如何將doInBackground方法與調用worker的線程進行同步?正在調用SwingWorker運行錯誤以及如何同步doInBackground?
我用下面的代碼,但它似乎是創建一個線程鎖:
private Object LOCK = new Object();
public final void method() {
someObject.before();
SwingWorker<Void, Void> worker1 = new SwingWorker<Void, Void>() {
protected Void doInBackground() throws Exception {
methodExt();
return null;
}
protected void done() {
someObject.after();
synchronized (LOCK) {
LOCK.notifyAll();
}
}
};
worker1.execute();
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException exception) {
exception.printStackTrace();
}
}
}
好吧,基本上,你已經規避了SwingWorker給你的任何好處,因爲'LOCK.wait'會阻止EDT ...更好的是使用某種[Observer Pattern](http: //www.oodesign.com/observer-pattern.html)告訴你什麼時候完成了......我不知道,可能會喜歡用'PropertyChangeListener' ....? – MadProgrammer 2015-02-24 09:49:30
@MadProgrammer我看不到PropertyChangeListener如何幫助我。我可以調用someObject.before(); methodExt(); someObject.after();但是然後methodExt在EDT上運行,這是一個錯誤,這就是爲什麼我使用SwingWorker,因爲它有一個我可以使用的直接完成的方法。我的意思是我可以創建一個調用methodExt()的新線程,然後在此線程中創建一個新的Runnable,調用someObject.after()並在EDT上調用它,但我認爲SwingWorker是一種更優雅的方式。 – Mac 2015-02-24 10:22:29
但是,你的LOCK阻塞了EDT ......並且從內存中,你可以簡單地調用SwingWorker#get,這將阻塞到doInBackground返回... – MadProgrammer 2015-02-24 10:37:05