Guava的ListenableFuture是对多线程使用的一个很好的补充,通过ListenableFuture的addCallback我们可以很好的完成调用成功(onSuccess)或者失败(onFailure)以后的逻辑处理,使用方法如下:
@Slf4j
public class ListenableFutureDemo implements Callable{
String info;
public ListenableFutureDemo(String info) {
this.info = info;
}
public static void main(String[] args) {
log.info("----起床干活----");
ExecutorService pool = Executors.newFixedThreadPool(10);
//包装成Listenable的线程池
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
ListenableFuture future1 = executorService.submit(new ListenableFutureDemo("昨夜西风凋碧树"));
ListenableFuture future2 = executorService.submit(new ListenableFutureDemo("独上高楼"));
Futures.addCallback(future1, new CallBackDemo(), MoreExecutors.directExecutor());
Futures.addCallback(future2, new CallBackDemo(), pool);
log.info("----结束干活----");
}
@Override
public String call() throws Exception {
return info;
}
}
@Slf4j
class CallBackDemo implements FutureCallback {
@Override
public void onSuccess(@NullableDecl String o) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
log.info("------{}-------", o);
}
@Override
public void onFailure(Throwable throwable) {
log.info("----难以置信的报错----------");
}
}
以下是对常用类的介绍:
MoreExecutors:该类是final类型的工具类,提供了很多静态方法。比如ListeningDecorator方法将java线程池装饰为ListeningExecutorService,使用此实例submit方法即可初始化ListenableFuture对象。
ListeningExecutorService:该类是对ExecutorService的扩展,重新ExecutorService类中的submit方法,返回ListenableFuture对象。
ListenableFuture:该接口扩展了Future接口,增加了addListener方法,该方法在给定的executor上注册一个监听器,当计算完成时会马上调用该监听器。不能够确保监听器执行的顺序,但可以在计算完成时确保马上被调用。addListener和addCallback本质是一样的,addCallback是在addListener的基础上做了封装。
FutureCallback:该接口提供了OnSuccess和OnFailure方法。获取异步计算的结果并回调。
Futures:该类提供了很多实用的静态方法以供实用。
ListenableFutureTask:该类扩展了FutureTask类并实现了ListenableFuture接口,增加了addListener方法。
///将一个 ExecutorService 转换为 ListeningExecutorService,MoreExecutors装饰
ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
//Guava提供两个callBack用于ListenableFuture回调,高版本已经去掉第二个方法
Futures.addCallback(ListenableFuture future, FutureCallback super V> callback, Executor executor);
Futures.addCallback(ListenableFuture future, FutureCallback super V> callback);
// 但是你可以继续设置当前线程
MoreExecutors.directExecutor()
Futures和其他相关方法罗列
@Slf4j
public class GuavaDemo implements Callable {
static ListeningExecutorService executorService = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));
public static void main(String[] args) {
// ThreadFactoryBuilder 方便的threadFactory---
//ThreadFactory threadFactory = new ThreadFactoryBuilder().setNameFormat("测试").build();
testSettableFuture(); //规定时间拿到结果;适合需要在规定时间拿结果的应用
}
public static void testFutures(){
/**
* Futures相关
**/
//Futures.transform:对于ListenableFuture的返回值进行转换。
//allAsList:对多个ListenableFuture的合并,返回一个当所有Future成功时返回多个Future返回值组成的List对象。注:当其中一个Future失败或者取消的时候,将会进入失败或者取消。
//successfulAsList:和allAsList相似,唯一差别是对于失败或取消的Future返回值用null代替。不会进入失败或者取消流程。
//immediateFuture/immediateCancelledFuture: 立即返回一个待返回值的ListenableFuture。
//将ListenableFuture 转换成CheckedFuture。CheckedFuture 是一个ListenableFuture ,其中包含了多个版本的get 方法,方法声明抛出检查异常.这样使得创建一个在执行逻辑中可以抛出异常的Future更加容易
//JdkFutureAdapters.listenInPoolThread(future): guava同时提供了将JDK Future转换为ListenableFuture的接口函数。
}
// SettableFuture 规定时间拿到结果;适合需要在规定时间拿结果的应用
public static void testSettableFuture(){
SettableFuture settableFuture = SettableFuture.create();
executorService.submit(new Callable() {
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(5);
settableFuture.set("得到世界");
log.info("会继续走下去么??");
return "测试";
}
});
try {
log.info("-----" + settableFuture.get(2, TimeUnit.SECONDS));
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
}
}
@Override
public String call() throws Exception {
TimeUnit.SECONDS.sleep(2);
return "测试";
}
@Slf4j
public class FuturesMethodDemo {
public static List createTickets() {
List list = new ArrayList<>();
for (int i = 0; i < 100; i++) {
list.add("车票" + i);
}
return list;
}
public static void main(String[] args) {
List list = createTickets();//获取车票
List> futures = Lists.newArrayList();
ExecutorService pool = Executors.newFixedThreadPool(10);//定义线程数
ListeningExecutorService executorService = MoreExecutors.listeningDecorator(pool);
for (int i = 0; i < list.size(); i++) {
futures.add(executorService.submit(new Task(list.get(i))));
}
/** successfulAsList和allAsList **/
ListenableFuture> resultsFuture = Futures.successfulAsList(futures);
//ListenableFuture> resultsFuture = Futures.allAsList(futures);
// try {
// //所有都执行完毕
// List integers = resultsFuture.get();
// log.info("结果:" + integers.stream().map(i -> i + "").collect(Collectors.joining(",")));
// } catch (Exception e) {
// log.error("出错了", e);
// } finally {
// log.info("操作完毕");
// pool.shutdown();
// }
/** AsyncFunction和 immediateFuture **/
ListenableFuture transformAsync = Futures.transformAsync(resultsFuture, new AsyncFunction, String>() {
@Override
public ListenableFuture apply(@NullableDecl List result) throws Exception {
return Futures.immediateFuture(result.stream().map(i -> i + "").collect(Collectors.joining(",")));
}
}, pool);
try {
log.info("转换后的结果{}", transformAsync.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}