轉載: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執行者服務,即任務將在調用者的線程上運行。