Java:有没有办法向Executor
添加一个监听器?
我有一个Future
的集合,我试图监控它,以更新一些GUI状态。目前我正在检查后台线程,如果提交/完成的任务有差异,但我在while(true){}
块中这样做,我不喜欢这种方法。
答案 0 :(得分:2)
您可以使用SwingWorkers或类似的类,具体取决于您的GUI工具包,以便在任务完成时收到通知。
答案 1 :(得分:1)
不幸的是,没有办法做到这一点。
相反,请使用Google的ListenableFuture<V>
interface
或者,使用具有更好异步支持的语言,例如C#和TPL。
答案 2 :(得分:1)
如果您想在任务完成时执行某些操作,请将其添加到任务本身。
public static <T> void addTask(Callable<T> tCall) {
executor.submit(new Runnable() {
public void run() {
T t = tCall.call();
// what you want done when the task completes.
process(t);
}
});
}
答案 3 :(得分:1)
使用java.util.concurrent.ExecutorCompletionService而不是Executor来提交任务。它有方法take(),它返回最近完成的任务。启动在循环中调用take()
的其他线程(或SwingWorker),并使用结果更新GUI状态。
答案 4 :(得分:0)
我做了类似于@Peter Lawrey的回答。
我添加了一个侦听器作为callable的成员变量,并在Callable返回其结果之前调用了该侦听器。
所以你有一个Listener接口:
@FunctionalInterface
public interface Listener<T> {
void notify(T result);
}
可以将其作为成员变量进行调用:
public class CallbackCallable implements Callable<String>{
private Listener<String> listener;
@Override
public String call() throws Exception {
// do some stuff
if (listener != null)
listener.notify("result string");
return "result string";
}
public void setListener(Listener<String> listener) {
this.listener = listener;
}
}
在你的应用程序中,你传递了一个监听器的实现,你想要对结果做些什么:
public static void main(String[] args) {
ExecutorService es = Executors.newSingleThreadExecutor();
System.out.println("This is thread: " + Thread.currentThread().getName());
CallbackCallable myCallable = new CallbackCallable();
myCallable.setListener(r -> {
// process your callable result here
System.out.println("Got from Callable: " + r);
System.out.println("This is thread: " + Thread.currentThread().getName());
});
es.submit(myCallable);
}
您唯一需要记住的是,您的实现将在与Callable相同的线程上运行,如您运行它可以看到:
This is thread: main
Got from Callable: result string
This is thread: pool-1-thread-1