Futures.addCallback如何保证在执行未来任务的线程上执行回调?

时间:2015-09-30 10:29:05

标签: java concurrency guava

代码如下所示:

final ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(4));

final Callable<String> asyncTask = new Callable<String>() {
    @Override
    public String call() throws Exception {
    return TestFuture.computeResult();
    }
};

final int listSize = 10;

final List<ListenableFuture<String>> listenableFutures = Lists.newArrayListWithExpectedSize(listSize);
for (int i = 0; i < listSize; i++) {
    listenableFutures.add(executor.submit(asyncTask));
}

for (final ListenableFuture<String> listenableFuture2 : listenableFutures) {
    Futures.addCallback(listenableFuture2, new FutureCallback<String>() {
    @Override
    public void onSuccess(final String result) {
        System.out.println("callback success with " + result + " at " + Thread.currentThread().getName());
    }

    @Override
    public void onFailure(final Throwable thrown) {
        System.out.println("callback failed with " + thrown.getMessage());
    }
    });
}

我无法弄清楚是否计划在将执行asyncTask的线程上执行回调?

我可以看到Futures.addCallback调用addCallback(future, callback, MoreExecutors.sameThreadExecutor());,但我不知道MoreExecutors.sameThreadExecutor如何保证这一点?

1 个答案:

答案 0 :(得分:1)

sameThreadExecutor()只会执行内联传递给Runnable方法的任何execute(Runnable):也就是说,它只是在其上调用run()。它根本不涉及任何线程。并且回调Runnable将在执行Executor的同一线程上传递给关联的asyncTask,因为ListeningExecutorService有效地将asyncTask包裹在done()中3}}在调用asyncTask方法时调用所有回调。

注意: 实际上保证所有回调都将在执行asyncTask的线程上执行。例如,如果您在 Executor完成后添加回调,则会在您添加回调的主题上执行(假设您不提供)要使用回调的sameThreadExecutor()以外的var app= angular.module('app', []);