Runnable 是一个接口,里面只声明了一个方法run();返回值为void所以无法拿到执行完的结果。只能通过共享变量或者线程通信来搞定。
Future就是对具体的Runable或者Callable任务的执行结果进行取消,查询是否完成,获取结果。
FutureTask实现了RunnableFuture接口,RunableFuture接口继承了Runable和Future接口,所以他既可以被线程执行,也可以作为Future得到Callable的返回值。
CompletableFutures是java8中新增加的一个类,主要用来处理异步。CompletableFuture不但可以调用get()方法获取执行结果,也可以使用回调函数来得到处理结果CompletableFuture可以通过completeExceptionally 函数来发出异常通知,同时我们也可以显示声明异常处理。CompletableFuture还有许多方法,来满足不同的需求场景,具体的方法 还需要使用到的时候在来进行具体分析。

在两个线程里并行执行任务A和任务B,只要有一个任务完成了,就执行任务C。代码如下:

  1. import java.time.LocalTime;
  2. import java.util.Random;
  3. import java.util.concurrent.CompletableFuture;
  4. import java.util.concurrent.ExecutionException;
  5. import java.util.concurrent.ExecutorService;
  6. import java.util.concurrent.Executors;
  7. import java.util.concurrent.Future;
  8. import java.util.concurrent.TimeUnit;
  9. import java.util.concurrent.TimeoutException;
  10. public class LearnCompleteFuture {
  11. private static Random random = new Random();
  12. public static void main(String[] args) throws InterruptedException, ExecutionException {
  13. useFuture();
  14. TimeUnit.SECONDS.sleep(10);
  15. System.out.println();
  16. useCompletableFuture();
  17. }
  18. private static void useFuture() throws InterruptedException, ExecutionException {
  19. System.out.println("Future");
  20. ExecutorService exector = Executors.newFixedThreadPool(3);
  21. Future<Void> futureA = exector.submit(() -> work("A1"));
  22. Future<Void> futureB = exector.submit(() -> work("B1"));
  23. while (true) {
  24. try {
  25. futureA.get(1, TimeUnit.SECONDS);
  26. break;
  27. } catch (TimeoutException e) {
  28. }
  29. try {
  30. futureB.get(1, TimeUnit.SECONDS);
  31. break;
  32. } catch (TimeoutException e) {
  33. }
  34. }
  35. exector.submit(() -> work("C1")).get();
  36. exector.shutdown();
  37. }
  38. private static void useCompletableFuture() throws InterruptedException, ExecutionException {
  39. System.out.println("CompletableFuture");
  40. CompletableFuture<Void> futureA = CompletableFuture.runAsync(() -> work("A2"));
  41. CompletableFuture<Void> futureB = CompletableFuture.runAsync(() -> work("B2"));
  42. futureA.runAfterEither(futureB, () -> work("C2")).get();
  43. }
  44. public static Void work(String name) {
  45. System.out.println(name + " starts at " + LocalTime.now());
  46. try {
  47. TimeUnit.SECONDS.sleep(random.nextInt(10));
  48. } catch (InterruptedException e) {
  49. }
  50. System.out.println(name + " ends at " + LocalTime.now());
  51. return null;
  52. }
  53. }

两种方法useFuture和useCompletableFuture相比:

首先,方法2 比 方法1 的代码简单。在方法1里,既要自己照顾线程池的创建和销毁,还要负责对任务A和任务B的监控。而方法2,只需要用CompletableFuture的runAfterEither就完成了任务A、任务B和任务C之间的依赖关系的定义。

在方法2,甚至用一行代码就能完成:

  1. CompletableFuture.runAsync(() -> work("A2")).runAfterEither(CompletableFuture.runAsync(() -> work("B2")), () -> work("C2")).get();

其次,方法2 比 方法1 高效。

方法1的主线程,要通过while(true)的方式不断地轮询任务A和任务B的运行状况,浪费CPU资源,而方法2的主线程只需要在最后的get()上静静地等待任务C的完成。

http://blog.csdn.net/zjysource/article/details/54409772

最新文章

  1. ios10 xcode8 适配的那些事
  2. python:Django
  3. 【SFTP】使用Jsch实现Sftp文件下载-支持断点续传和进程监控
  4. flex的http URL转码与解码
  5. Kth Largest Element in an Array - LeetCode
  6. node中的模块
  7. JQuery合并列(可用于导出Word)
  8. 以Facebook为案例剖析科技公司应有的工具文化
  9. MacOS U盘安装
  10. java线程中的sleep/wait/notify/yield/interrupt方法 整理
  11. 《Javascript高级程序设计》读书笔记之bind函数详解
  12. css单独设定样式
  13. Spring Cloud学习笔记-003
  14. 根据iOS 10 的新特性,创建iMessage App,可用于自定义表情
  15. 查找修补文件差异diff、patch
  16. 2018总结--&gt;2019新目标
  17. SparkSql处理嵌套json数据
  18. JS的一些小知识
  19. opencv车流量统计算法
  20. (转)干货|这篇TensorFlow实例教程文章告诉你GANs为何引爆机器学习?(附源码)

热门文章

  1. 梦想CAD控件 2018.7.26更新
  2. 03Microsoft SQL Server 数据类型
  3. block相关归纳
  4. iview“官方“实现的右键菜单
  5. js识别手机访问自动跳转到相应页面
  6. Servlet的说明及使用案例
  7. CCF201609-2 火车购票 java(100分)
  8. Mysql Group by 分组取最小的实现方法
  9. codeforces round #394 (div. 2) A\B 题解
  10. css &amp; no margin &amp; print pdf