Future接口是Java标准API的一部分,在java.util.concurrent包中。Future接口是Java线程Future模式的实现,可以来进行异步计算。

有了Future就可以进行三段式的编程了,1.启动多线程任务2.处理其他事3.收集多线程任务结果。从而实现了非阻塞的任务调用。在途中遇到一个问题,那就是虽然能异步获取结果,但是Future的结果需要通过isdone来判断是否有结果,或者使用get()函数来阻塞式获取执行结果。这样就不能实时跟踪其他线程的结果状态了,所以直接使用get还是要慎用,最好配合isdone来使用。

这里有一种更好的方式来实现对任意一个线程运行完成后的结果都能及时获取的办法:使用CompletionService,它内部添加了阻塞队列,从而获取future中的值,然后根据返回值做对应的处理。一般future使用和CompletionService使用的两个测试案例如下:

1. 获取到的结果的顺序和Future放入列表的顺序一致

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;/*** 多线程执行,异步获取结果* * @author i-clarechen**/
public class AsyncThread {public static void main(String[] args) {AsyncThread t = new AsyncThread();List<Future<String>> futureList = new ArrayList<Future<String>>();t.generate(3, futureList);t.doOtherThings();t.getResult(futureList);}/*** 生成指定数量的线程,都放入future数组* * @param threadNum* @param fList*/public void generate(int threadNum, List<Future<String>> fList) {ExecutorService service = Executors.newFixedThreadPool(threadNum);for (int i = 0; i < threadNum; i++) {Future<String> f = service.submit(getJob(i));fList.add(f);}service.shutdown();}/*** other things*/public void doOtherThings() {try {for (int i = 0; i < 3; i++) {System.out.println("do thing no:" + i);Thread.sleep(1000 * (new Random().nextInt(10)));}} catch (InterruptedException e) {e.printStackTrace();}}/*** 从future中获取线程结果,打印结果* * @param fList*/public void getResult(List<Future<String>> fList) {ExecutorService service = Executors.newSingleThreadExecutor();service.execute(getCollectJob(fList));service.shutdown();}/*** 生成指定序号的线程对象* * @param i* @return*/public Callable<String> getJob(final int i) {final int time = new Random().nextInt(10);return new Callable<String>() {@Overridepublic String call() throws Exception {Thread.sleep(1000 * time);return "thread-" + i;}};}/*** 生成结果收集线程对象* * @param fList* @return*/public Runnable getCollectJob(final List<Future<String>> fList) {return new Runnable() {public void run() {for (Future<String> future : fList) {try {while (true) {if (future.isDone() && !future.isCancelled()) {System.out.println("Future:" + future+ ",Result:" + future.get());break;} else {Thread.sleep(1000);}}} catch (Exception e) {e.printStackTrace();}}}};}}

运行结果打印和future放入列表时的顺序一致,为0,1,2:

do thing no:0
do thing no:1
do thing no:2
Future:java.util.concurrent.FutureTask@68e1ca74,Result:thread-0
Future:java.util.concurrent.FutureTask@3fb2bb77,Result:thread-1
Future:java.util.concurrent.FutureTask@6f31a24c,Result:thread-2

2. 先获取到最先结束的线程结果

import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.CompletionService;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.LinkedBlockingDeque;public class testCallable {public static void main(String[] args) {try {completionServiceCount();} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}/*** 使用completionService收集callable结果* @throws ExecutionException * @throws InterruptedException */public static void completionServiceCount() throws InterruptedException, ExecutionException {ExecutorService executorService = Executors.newCachedThreadPool();CompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(executorService);int threadNum = 5;for (int i = 0; i < threadNum; i++) {completionService.submit(getTask(i));}int sum = 0;int temp = 0;for(int i=0;i<threadNum;i++){temp = completionService.take().get();sum += temp;System.out.print(temp + "\t");}System.out.println("CompletionService all is : " + sum);executorService.shutdown();}public static Callable<Integer> getTask(final int no) {final Random rand = new Random();Callable<Integer> task = new Callable<Integer>() {@Overridepublic Integer call() throws Exception {int time = rand.nextInt(100)*100;System.out.println("thead:"+no+" time is:"+time);Thread.sleep(time);return no;}};return task;}
}

运行结果为最先结束的线程结果先被处理:

thead:0 time is:4200
thead:1 time is:6900
thead:2 time is:2900
thead:3 time is:9000
thead:4 time is:7100
2    0    1    4    3    CompletionService all is : 10

利用Future异步获取多线程的返回结果相关推荐

  1. java 利用Future异步获取多线程任务结果

    2019独角兽企业重金招聘Python工程师标准>>> 简述 Future接口是Java标准API的一部分,在java.util.concurrent包中.Future接口是Java ...

  2. java线程future_Java中多线程对运行结果怎么利用future获取

    Java中多线程对运行结果怎么利用future获取 发布时间:2020-12-07 17:11:08 来源:亿速云 阅读:124 作者:Leah Java中多线程对运行结果怎么利用future获取?针 ...

  3. C++ 多线程:future 异步访问类(线程之间安全便捷的数据共享)

    文章目录 future前言 future描述 future类成员使用 总结 future前言 首先查看如下代码 #include <iostream> #include <threa ...

  4. jQuery中的ajax、jquery中ajax全局事件、load实现页面无刷新局部加载、ajax跨域请求jsonp、利用formData对象向服务端异步发送二进制数据,表单序列化(异步获取表单内容)

    jQuery中使用ajax: 在jQuery中使用ajax首先需要引入jQuery包,其引入方式可以采用网络资源,也可以下载包到项目文件中,这里推荐下载包到文件中:市面上有多个版本的jQuery库,这 ...

  5. 利用Future接口实现异步线程同步回滚

    项目场景: 一个RBAC的权限管理架构 问题描述 大致就是在一个方法中开子线程进行异步数据处理, 如果业务处理失败肯定是要回退的, 而且这种父子线程相关连的业务肯定是要一起回退的, 那么问题来了, 异 ...

  6. python多线程返回值_python获取多线程及子线程的返回值

    最近有个需求,用多线程比较合适,但是我需要每个线程的返回值,这就需要我在threading.Thread的基础上进行封装 import threading class MyThread(threadi ...

  7. QT 多线程异步获取htpp信息 网络通信

    自己封装的获取http.https信息的模块,多线程.异步获取,实现代理功能.在实际项目中运用多年,无bug. 下载地址:https://download.csdn.net/download/qq_3 ...

  8. python 多线程 异步_python 多线程异步

    最近做了个爬取代理的爬虫,使用了python的aysncio及concurrent.futures的ThreadPoolExecutor(线程池)技术,最终完成了多线程下的异步抓取,在此mark下,以 ...

  9. 如何获取多线程执行结果-java

    在日常的项目开发中,我们会经常遇到通过多线程执行程序并需要返回执行结果的场景,下面我们就对获取多线程返回结果的几种方式进行一下归纳,并进行简要的分析与总结. 一.Thread.join 在一些简单的应 ...

最新文章

  1. 抽样方法,采样方法 shuffle
  2. 【数理知识】《积分变换与场论》王振老师-第3章-矢量与矢量空间
  3. 读书笔记《单核工作法》_4原理4,5
  4. Scala语言整理(一)
  5. 【CF1338C】Perfect Triples【位运算】【构造】
  6. const类型成员函数与mutable
  7. CVPR 2021 论文开放下载了!
  8. ipad safari php readfile mp4,php – 在mac上的safari中没有加载Wav文件
  9. WINDOWS上传文件到LINUX中文乱码
  10. 给硬盘分个整数大小的区
  11. 华为盒子m330能生鸿蒙吗,不仅能看片 教你怎么玩转华为M330盒子
  12. 网格交易法:数学+传统智慧战胜华尔街
  13. 一文详解工业相机和镜头选取
  14. oracle取字段第三位字符,oracle字符串根据分隔符号获取第几个元素
  15. 提示fxp不是一个目标文件
  16. 二进制部署多master节点的k8s集群-1.20以上稳定版本
  17. QT3D场景的快速绘制
  18. 网络工程属于计算机还是通信,通信工程属于计算机大类吗 哪个大类
  19. 自动驾驶和辅助驾驶基础知识
  20. 有关clipToPadding、 clipChildren的那些事

热门文章

  1. 方法的形式参数是类名的时候如何调用
  2. Python多线程及其使用方法
  3. Swift -- 7.5 类型属性,方法
  4. Android 图标上面添加提醒(二)使用开源UI类库 Viewbadger
  5. Python的datetime
  6. sqlserver中的分页sql语句,不同于mysql中的limit,相当于top+top
  7. 【开源软件】windows环境下libcurl编译
  8. [BAT]TASKKILL 杀进程
  9. JavaScript OO不XX 学习总结
  10. 软件测试Bug管理规范