转载:https://my.oschina.net/realfighter/blog/349929
Guava提供了 FutureCallback接口,FutureCallback接口提供了onSuccess 和onFailure 方法,onSuccess 方法以Future任务的执行结果作为参数,因此我们就可以在成功时候获取任务执行的结果,做进一步的处理了。
使用 FutureCallback非常简单,我们以类似的方式向ListenableFuture注册一个回调接口,我们不需要直接向 ListenableFuture添加FutureCallback回调函数,而是直接使用Futures.addCallback方法。Futures 类提供了一些有用的、用于处理Future实例的静态方法集合,接下来我们来看一个例子,首先来看一个简单的FutureCallback接口的实现:
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.junit.Test;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
public class FutureCallbackImpl implements FutureCallback<Person> {
private StringBuilder builder = new StringBuilder();
@Override
public void onSuccess(Person result) {
builder.append(result).append(" successfully");
}
@Override
public void onFailure(Throwable t) {
builder.append(t.toString());
}
public String getCallbackResult() {
return builder.toString();
}
@Test
public void testFutureCallback() {
// 创建一个线程缓冲池Service
ExecutorService executor = Executors.newCachedThreadPool();
// 创建一个ListeningExecutorService实例
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(executor);
// 提交一个可监听的线程(可以返回自定义对象,也可直接返回String)
ListenableFuture<Person> futureTask = executorService.submit(new Callable<Person>() {
Person p = new Person();
@Override
public Person call() throws Exception {
// return "Task completed";
p.setName("gogo");
return p;
}
});
FutureCallbackImpl callback = new FutureCallbackImpl();
// 线程结果处理回调函数
Futures.addCallback(futureTask, callback);
// 如果callback中执行的是比较费时的操作,Guava建议使用以下方法。
// Futures.addCallback(futureTask,callback,executorService);
// 处理后的线程执行结果:"Task completed successfully"
System.out.println(callback.getCallbackResult());
// assertThat(callback.getCallbackResult(), is("Task completed successfully"));
}
}
Futures.addCallback(futureTask,callback,executorService);
这个方法,FutureCallback操作将会执行在单独的线程,这个线程由传入的ExecutorService参数提供。否则的话,初始 ListenableFuture实例执行的线程将会执行FutureCallback操作,就像ThreadPoolExecutor、 CallerRunsPolicy执行者服务,即任务将在调用者的线程上运行。