我在像这样的类中有一个线程 -
import java.util.Observable;
public class Download extends Observable {
private int state = 0;
private final Thread myThread = new Thread(() -> {
/*
some work to do here
*/
setChanged();
notifyObservers(state);
});
public void download(int state) {
if (!myThread.isAlive()) {
this.state = state;
myThread.start();
}
}
public Thread getThread() {
return myThread;
}
public static void MyMethod() throws InterruptedException {
Download down = new Download();
down.addObserver((Observable ob, Object dat) -> {
System.out.println(ob);
if ((int) dat == 1) {
down.download(2);
} else {
System.out.println("success");
}
});
down.download(1);
down.getThread().join();
}
public static void main() throws InterruptedException {
MyMethod();
}
}
问题是我从来没有打印过"success"
消息。
我认为,这是因为所有观察者都是从MyThread
内部得到通知的。因此,当down.download(2)
内的观察者调用MyMethod()
时,前一个线程仍在运行,并且忽略该调用。
如何通过主线程而不是myThread
通知所有观察者?
答案 0 :(得分:1)
您正在执行down.download(2)
内调用MyThread
,因此线程仍处于活动状态,这意味着您的下载方法因if(!myThread.isAlive())
而无效。
我建议您使用Executor framework和Listenable Futures from Guava,而不是手动创建线程。来自Guava wiki的示例代码:
ListeningExecutorService service =
MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
ListenableFuture<Explosion> explosion = service.submit(new Callable<Explosion>() {
public Explosion call() {
return pushBigRedButton();
}
});
Futures.addCallback(explosion, new FutureCallback<Explosion>() {
// we want this handler to run immediately after we push the big red button!
public void onSuccess(Explosion explosion) {
walkAwayFrom(explosion);
}
public void onFailure(Throwable thrown) {
battleArchNemesis(); // escaped the explosion!
}
});
注意Futures.addCallback(..)也有一个重载,允许你确定哪个执行者应该执行回调,这似乎是你想要的。