如何获取任务执行结果

Java通过ThreadPoolExecutor提供的三个submit()方法和一个FutureTask工具类来支持获得任务执行结果的需求。


// 提交Runnable任务
Future<?> submit(Runnable task);
// 提交Callable任务
<T> Future<T> submit(Callable<T> task);
// 提交Runnable任务及结果引用
<T> Future<T> submit(Runnable task, T result);

Future接口有下面5个方法,其中最后一个get(timeout,unit)支持超时机制。通过Future接口的5个方法,你会发现,我们提交的任务不但能够获取任务执行结果,还可以取消任务。不过值得注意的是:这两个get方法都是阻塞式的,如果被调用的时候,任务还没有执行完,那么调用get方法的线程会阻塞,指导任务执行完才会被唤醒。


// 取消任务
boolean cancel(boolean mayInterruptIfRunning);
// 判断任务是否已取消
boolean isCancelled();
// 判断任务是否已结束
boolean isDone();
// 获得任务执行结果
get();
// 获得任务执行结果,支持超时
get(long timeout, TimeUnit unit);

这3个submit方法之间的区别在于方法参数不同:

  1. 提交Runnbale任务submit(Runnable task):这个方法参数Runnable的run方法是没有返回值的,所以这个方法返回的Future仅可以用来断言任务已经结束,类似于Thread.join();
  2. 提交Callable任务submit(Callable<T> task):这个方法的参数是一个Callable接口,只有一个call方法,并且这个方法是有返回值的,可以通过get方法来获取任务执行结果。
  3. 提交Runnable任务及结果引用submit(Runnable task, T result):假设这个方法返回Future对象时f,f.get的返回值就是传给submit方法的参数result,result相当于主线程和子线程之间的桥梁,通过它主子线程可以共享数据。
public class FutureDemo {static class Result{private String resultStr;public String getResultStr() {return resultStr;}public void setResultStr(String resultStr) {this.resultStr = resultStr;}}static class Task implements Runnable{Result r;public Task(Result r) {this.r = r;}@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":" + r.getResultStr());r.setResultStr("hello Java");System.out.println(Thread.currentThread().getName() + ":" + r.getResultStr());}}public static void main(String[] args) throws ExecutionException, InterruptedException {ExecutorService executor = Executors.newFixedThreadPool(1);Result result = new Result();result.setResultStr("hello world");Future<Result> future = executor.submit(new Task(result), result);System.out.println(Thread.currentThread().getName() + ":" + result.getResultStr()); // hello worldSystem.out.println(Thread.currentThread().getName() + ":" + future.get().getResultStr()); // hello Java}
}

FutureTask工具类


FutureTask(Callable<V> callable);
FutureTask(Runnable runnable, V result);

// 创建FutureTask
FutureTask<Integer> futureTask= new FutureTask<>(()-> 1+2);
// 创建线程池
ExecutorService es = Executors.newCachedThreadPool();
// 提交FutureTask
es.submit(futureTask);
// 获取计算结果
Integer result = futureTask.get();

// 创建FutureTask
FutureTask<Integer> futureTask= new FutureTask<>(()-> 1+2);
// 创建并启动线程
Thread T1 = new Thread(futureTask);
T1.start();
// 获取计算结果
Integer result = futureTask.get();

实现最优的"烧水泡茶"程序

 public static void main(String[] args) {FutureTask<String> task2 = new FutureTask<>(()->{System.out.println("洗茶壶");System.out.println("洗茶杯");System.out.println("拿茶叶");return "茶叶AAA";});FutureTask task1 = new FutureTask(new FutureTask2(task2));Thread t1 = new Thread(task1);Thread t2 = new Thread(task2);t1.start();t2.start();}static class FutureTask2 implements Callable<String>{FutureTask<String> f1;public FutureTask2(FutureTask<String> f1) {this.f1 = f1;}@Overridepublic String call() throws Exception {System.out.println("洗水壶");System.out.println("烧开水");System.out.println("泡茶"+f1.get());return "";}}

Java中带返回值的线程池Future相关推荐

  1. Java中带返回值的方法的定义与调用

    带返回值的方法定义: public static 数据类型 方法名(参数){return 数据;} 与前文中带返回值的方法定义不同的是,void变成了数据类型,对应return后紧跟的数据.这里顺便说 ...

  2. Java中带返回值的方法

    带返回值方法的定义: public static 数据类型 方法名(参数){ return 数据: } 例如: public static boolean jiou(int number){ retu ...

  3. C++ 多线程之带返回值的线程处理函数

    写在前面:         又是学C扎扎的一天,C扎扎学起来果然扎手.如果你能坚持看到文章最后,你会发现,好吧有可能你啥也发现不了,因为后面什么也没有~~~ 目录 1. 使用 async 函数创建线程 ...

  4. c++中带返回值函数没写return能通过编译但运行时会出现奇怪问题

    c++中带返回值函数没写return能通过编译但运行时会出现奇怪问题 例如: string myFunc(){ theLogics(); } 发现调用: myFunc(); 崩溃. 但调用: cout ...

  5. java中的返回值到底有什么用?

    今天看到一个有意思的问题:java中的返回值到底有什么用? 看到了一个高赞回答如下: 你是公司的老总,然后你跟你秘书说,我想要两张的电影票.然后,你秘书去排队买票,最后把两张电影票给你,这两张电影票就 ...

  6. Java中常用的四种线程池

    在Java中使用线程池,可以用ThreadPoolExecutor的构造函数直接创建出线程池实例,在Executors类中,为我们提供了常用线程池的创建方法. ​ 接下来我们就来了解常用的四种: ne ...

  7. java自带的四种线程池

    java预定义的哪四种线程池? newSingleThreadExexcutor:单线程数的线程池(核心线程数=最大线程数=1) newFixedThreadPool:固定线程数的线程池(核心线程数= ...

  8. java中return返回值_Java中return的用法

    展开全部 一.return语句总是用在方法中,有两个作用. 一个是返回方法指定类型的值(这个值总62616964757a686964616fe59b9ee7ad9431333366306434是确定的 ...

  9. java中resultset返回值_JDBC基础教程之ResultSet对象 | 学步园

    ResultSet 包含符合 SQL 语句中条件的所有行,并且它通过一套 get 方法(这些 get 方法可以访问当前行中的不同列)提供了对这些行中数据的访问.ResultSet.next 方法用于移 ...

最新文章

  1. pid调节软件_科学or艺术?——如何优化PID回路以实现最优性能
  2. delphi中的函数传参如何传枚举参数_shell脚本的函数介绍使用和工作常用案例。建议收藏...
  3. 如何在GraphPad Prism中使用非线性回归拟合模型?
  4. 无锁HashMap的原理与实现
  5. C/C++ 基本类型注意事项
  6. 喵哈哈村的魔法考试 Round #1 (Div.2) C 喵哈哈村的魔法石(II) 背包dp
  7. 3198元起!vivo X27/X27 Pro发布 升降摄像头+4800万三摄
  8. android sdk离线安装
  9. Redis--zset类型操作命令
  10. HP P2000 G3阵列故障经历
  11. es6学习推荐网址(阮一峰)
  12. FPGA数字时钟计数器
  13. 硬件工程师成长之路(10)——项目举例
  14. Win2008:在 Win2008R2 中安装 PowerShell 4.0 (旧作)
  15. java中未处理的异常_Java中未处理的异常
  16. 服务器入门/tomcat以及如何部署
  17. JavaScript 获取字符串的最后一个字符
  18. Flink实时数据处理实践经验(Flink去重、维表关联、定时器、双流join)
  19. 从IMDB上爬取MovieLens数据集中的详细电影信息
  20. Pytorch SoftMax回归

热门文章

  1. nginx入门-个人总结
  2. 对于表单提交的防止重复提交
  3. 编写函数swap实现两个数据的互换,形参分别指针和引用
  4. CC(Smart3D)航拍影像结合激光雷达创建实景三维模型(视频教程可下载)
  5. 哪里可以下载Holer软件包
  6. java 高内聚低耦合_高内聚低耦合法则实例解析
  7. [Andoid][踩坑]CTS 11_r3开始出现的testBootClassPathAndSystemServerClasspath_nonDuplicateClasses FAIL问题分析
  8. 张量网络系列(一 从张量到张量网络)
  9. 信号幅值归一化(Python)
  10. idea启动项目报错内存资源不足的问题