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

Java多线程相关的常用接口的更多相关文章

  1. Java多线程相关的

    很多小伙伴在学习Java的时候,总是感觉Java多线程在实际的业务中很少使用,以至于不会花太多的时间去学习,技术债不断累积!等到了一定程度的时候对于与Java多线程相关的东西就很难理解,今天需要探讨的 ...

  2. Java多线程相关面试题及答案-整理

    1.什么是线程? 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位.程序员可以通过它进行多处理器编程,你可以使用多线程对 运算密集型任务提速.比如,如果一个线程完成 ...

  3. Java[3] Java多线程相关资料

    Java多线程: http://www.uml.org.cn/j2ee/201509093.asp

  4. Java多线程-两种常用的线程计数器CountDownLatch和循环屏障CyclicBarrier

    Java多线程编程-(1)-线程安全和锁Synchronized概念 Java多线程编程-(2)-可重入锁以及Synchronized的其他基本特性 Java多线程编程-(3)-从一个错误的双重校验锁 ...

  5. 2018/1/15 JAVA多线程相关

    本文不说synchronized相关,它就是JAVA的一个保留关键字,jdk自己实现了它,但说真的,可应用场景真的少,相比lock接口,它还是被淘汰好吧; 首先,说说lock接口,lock接口是一个工 ...

  6. java多线程相关代码

    1.创建线程的三种方式 使用Thread package com.wpbxx.test; //1.自定义一个类,继承java.lang包下的Thread类 class MyThread extends ...

  7. Java多线程之实现Runnable接口

    package org.study2.javabase.ThreadsDemo.runnable; /** * @Auther:GongXingRui * @Date:2018/9/18 * @Des ...

  8. Java : JPA相关以及常用注解

    SpringDataJPA自定义的查询方法 定义规范       And 并且 Or 或     Is,Equals 等于 Between 两者之间 LessThan 小于 LessThanEqual ...

  9. Java多线程:实现API接口创建线程方式详解

    先看例子: /**实现Runnable接口创建线程步骤: * 1.创建一个实现Runnable接口的类 * 2.重写Runnable类中抽象的run()方法 * 3.创建实现类的对象 * 4.声明Th ...

随机推荐

  1. react-router 4.x 路由按需加载

    react-router 4 代码分割(按需加载) 官方文档  https://serverless-stack.com/chapters/code-splitting-in-create-react ...

  2. python3.7实现九九乘法表

    for i in range(1,10): for j in range(1,i+1): print("%d*%d=%d" % (i,j,i*j),end=" " ...

  3. <MyBatis>入门五 查询的返回值处理

    select : 返回对象:  <select  id = " "  resultType= "对象的全类名"  /> List: <sele ...

  4. java Beanutils.copyProperties( )用法

    这是一篇开发自辩甩锅稿~~~~ 昨天测试小姐姐将我的一个bug单重开了,emmmm....内心OS:就调整下对象某个属性类型这么简单的操作,我怎么可能会出错呢,一定不是我的锅!!but再怎么抗拒,bu ...

  5. unigui+fastreport 打印【4】

    1.建立一个uniForm,用于建立FastReport打印界面.在Form上增加uniFrame.和传统的的报表打印设计一样一样的. 2.在beofeShow事情中: procedure TUniF ...

  6. chrome源代码目录结构简介(版本4.1.249.1059)

    为了对庞大的源码项目进行分析,先对源码目录树作一个简单的介绍,粗略的了解一下各个模块的功能分布情况,chrome源代码src目录下的结构如下图: app:该目录下的代码主要是和各个操作系统平台相关的应 ...

  7. bzoj4518征途 斜率优化

    征途这是一道十分经典的斜率优化 我们可以从题目中的方差来想,也就很容易的到这个式子 \[ans=m^2*\frac{\sum_{i=1}^{m}{(x_i-{\overline{x}})^2}}{m} ...

  8. 使用C#执行PowerShell命令

    按照网上的教程配置会发生SSL链接错误 该文章的最后使用了SSL来保证账户在连接服务器的时候不发生账户认证错误,但是我经过测试发现这个是不可行的,有一种更为简单的方法 首先要对服务器进行winrm设置 ...

  9. [poj3537]Crosses and Crosses_博弈论

    Crosses and Crosses poj-3537 题目大意:给定一个1*n的网格,每次往格子内填一个$\times$,连续的三个即可获胜. 注释:$1\le n\le 2000$. 想法:我们 ...

  10. 函数式语言(functional language)定义、函数式语言的种类以及为什么函数式语言会流行起来的学习笔记

    一.什么是函数式语言?       函数式语言一类程序设计语言,是一种非冯·诺伊曼式的程序设计语言.函数式语言主要成分是原始函数.定义函数和函数型.这种语言具有较强的组织数据结构的能力,可以把某一数据 ...