有没有办法向Executor / Future添加一个监听器?

时间:2012-11-13 15:08:49

标签: java multithreading

Java:有没有办法向Executor添加一个监听器? 我有一个Future的集合,我试图监控它,以更新一些GUI状态。目前我正在检查后台线程,如果提交/完成的任务有差异,但我在while(true){}块中这样做,我不喜欢这种方法。

5 个答案:

答案 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