可以看一下代码,非常的直观:
public class JDKThreadPoolExecutorTest { public static void main(String[] args) throws Exception { ListeningExecutorService executor = MoreExecutors.listeningDecorator(Executors.newCachedThreadPool()); ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName()+"-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); return "化妆完毕了。"; }); Futures.addCallback(listenableFuture, new FutureCallback<String>() { @Override public void onSuccess(@Nullable String result) { System.out.println(Thread.currentThread().getName()+"-future的内容:" + result); } @Override public void onFailure(Throwable t) { System.out.println(Thread.currentThread().getName()+"-女神放你鸽子了。"); t.printStackTrace(); } }); System.out.println(Thread.currentThread().getName()+"-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); } }
有 onSuccess 方法和 onFailure 方法。
上面的程序输出结果为:
如果异步任务执行的时候抛出了异常,比如女神被她的男神约走了,异步任务改成这样:
ListenableFuture<String> listenableFuture = executor.submit(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); TimeUnit.SECONDS.sleep(5); throw new Exception("男神约我看电影,就不和你吃饭了。"); });
最终的运行结果就是这样:
加强版的Future - CompletableFuture
第一小节讲的 Future 是 JDK 1.5 时代的产物:
可以把这个接口理解为一个任务的某个阶段。所以多个 CompletionStage 链接在一起就是一个任务链。前一个任务完成后,下一个任务就会自动触发。
CompletableFuture 里面的方法非常的多。
由于篇幅原因,我就只演示一个方法:
public class JDKThreadPoolExecutorTest { public static void main(String[] args) throws Exception { CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } return "化妆完毕了。"; }); completableFuture.whenComplete((returnStr, exception) -> { if (exception == null) { System.out.println(Thread.currentThread().getName() + returnStr); } else { System.out.println(Thread.currentThread().getName() + "女神放你鸽子了。"); exception.printStackTrace(); } }); System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); } }
该方法的执行结果如下:
这个方法在很多开源框架里面使用的还是非常的多的。
接下来主要看看 CompletableFuture 对于异常的处理。我觉得非常的优雅。
不需要 try-catch 代码块包裹,也不需要调用 Future.get() 才知道异常了,它提供了一个 handle 方法,可以处理上游异步任务中出现的异常:
public class JDKThreadPoolExecutorTest { public static void main(String[] args) throws Exception { CompletableFuture.supplyAsync(() -> { System.out.println(Thread.currentThread().getName() + "-女神:我开始化妆了,好了我叫你。"); throw new RuntimeException("男神约我看电影了,我们下次再约吧,你是个好人。"); }).handleAsync((result, exception) -> { if (exception != null) { System.out.println(Thread.currentThread().getName() + "-女神放你鸽子了!"); return exception.getCause(); } else { return result; } }).thenApplyAsync((returnStr) -> { System.out.println(Thread.currentThread().getName() + "-" + returnStr); return returnStr; }); System.out.println(Thread.currentThread().getName() + "-等女神化妆的时候可以干点自己的事情。"); Thread.currentThread().join(); } }
由于女神在化妆的时候,接到男神的电话约她看电影,就只能放你鸽子了。
所以,上面程序的输出结果如下:
最后说一句(求关注)
按照我的经验,女神约出来了你需要准备好回答一个问题:
你看我今天有什么不同?
首先这题就是一道送命题,回答到她预期的答案的概率非常的低。有可能她今天不一样的地方就是换了一个指甲油、换了一个美瞳、换了一个耳环之类的。
很明显,这些非常细节的地方我们很难发现。但是别怂。
先含情脉脉的认真的盯着她,花一分钟找答案,一分钟后没有找到答案,就说:
你每天都不一样,每天都比昨天更加美丽。
好了,才疏学浅,难免会有纰漏,如果你发现了错误的地方,还请你在后台留言指出来,我对其加以修改。
感谢您的阅读,我坚持原创,十分欢迎并感谢您的关注。
我是 why,一个被代码耽误的文学创作者,不是大佬,但是喜欢分享,是一个又暖又有料的四川好男人。
还有,重要的事情说三遍: 欢迎关注我呀。 欢迎关注我呀。 欢迎关注我呀。