Java中多线程对运行结果怎么利用future获取

发布时间:2020-12-07 17:11:08

来源:亿速云

阅读:124

作者:Leah

Java中多线程对运行结果怎么利用future获取?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

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

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

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

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> futureList = new ArrayList>();

t.generate(3, futureList);

t.doOtherThings();

t.getResult(futureList);

}

/**

* 生成指定数量的线程,都放入future数组

*

* @param threadNum

* @param fList

*/

public void generate(int threadNum, List> fList) {

ExecutorService service = Executors.newFixedThreadPool(threadNum);

for (int i = 0; i < threadNum; i++) {

Future 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> fList) {

ExecutorService service = Executors.newSingleThreadExecutor();

service.execute(getCollectJob(fList));

service.shutdown();

}

/**

* 生成指定序号的线程对象

*

* @param i

* @return

*/

public Callable getJob(final int i) {

final int time = new Random().nextInt(10);

return new Callable() {

@Override

public String call() throws Exception {

Thread.sleep(1000 * time);

return "thread-" + i;

}

};

}

/**

* 生成结果收集线程对象

*

* @param fList

* @return

*/

public Runnable getCollectJob(final List> fList) {

return new Runnable() {

public void run() {

for (Future 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

下面是先执行完的线程先处理的方案:

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 completionService = new ExecutorCompletionService(

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

temp = completionService.take().get();

sum += temp;

System.out.print(temp + "\t");

}

System.out.println("CompletionService all is : " + sum);

executorService.shutdown();

}

public static Callable getTask(final int no) {

final Random rand = new Random();

Callable task = new Callable() {

@Override

public 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

0 1 4 3 CompletionService all is : 10

关于Java中多线程对运行结果怎么利用future获取问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

java线程future_Java中多线程对运行结果怎么利用future获取相关推荐

  1. java 线程分组_Java多线程可以分组,还能这样玩!

    前面的文章,栈长和大家分享过多线程创建的3种方式<实现 Java 多线程的 3 种方式>. 但如果线程很多的情况下,你知道如何对它们进行分组吗? 和 Dubbo 的服务分组一样,Java ...

  2. java里新建线程设置线程名字_多线程开发不得不掌握,设置和获取线程名称及JVM如何运行的...

    原标题:多线程开发不得不掌握,设置和获取线程名称及JVM如何运行的 欲善编程,多看.多敲.多讨论:动眼.动手.动大脑. 1 如何设置和获取线程名称 多线程的运行状态是不确定的,在程序开发过程中,想要获 ...

  3. java线程钥匙_Java多线程并发编程/锁的理解

    一.前言 最近项目遇到多线程并发的情景(并发抢单&恢复库存并行),代码在正常情况下运行没有什么问题,在高并发压测下会出现:库存超发/总库存与sku库存对不上等各种问题. 在运用了 限流/加锁等 ...

  4. java线程池_Java多线程并发:线程基本方法+线程池原理+阻塞队列原理技术分享...

    线程基本方法有哪些? 线程相关的基本方法有 wait,notify,notifyAll,sleep,join,yield 等. 线程等待(wait) 调用该方法的线程进入 WAITING 状态,只有等 ...

  5. java线程名_java多线程

    首先讲一下进程和线程的区别: 进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程. 线程:同一类线程共享代码和数据空间,每个线程有独立的运行栈 ...

  6. java线程基础_Java多线程基础

    前言 在我们工作和学习的过程中,Java线程我们或多或少的都会用到,但是在使用的过程上并不是很顺利,会遇到各种各样的坑,这里我通过讲解Thread类中的核心方法,以求重点掌握以下关键技术点: 线程的启 ...

  7. java线程 锁_Java多线程(二) 多线程的锁机制

    当两条线程同时访问一个类的时候,可能会带来一些问题.并发线程重入可能会带来内存泄漏.程序不可控等等.不管是线程间的通讯还是线程共享数据都需要使用Java的锁机制控制并发代码产生的问题.本篇总结主要著名 ...

  8. java 线程 组成_java多线程

    一:基本知识点 1.1线程与进程区别: 1.进程是资源分配的最小单位,线程是CPU调度的最小单位 2.一个进程由一个或多个线程组成 3.进程之间相互独立,每个进程都有独立的代码和数据空间,但同一进程下 ...

  9. java 线程通讯_java多线程(五)线程通讯

    1.1. 为什么要线程通信 多个线程并发执行时,在默认情况下CPU是随机切换线程的,有时我们希望CPU按我们的规律执行线程,此时就需要线程之间协调通信. 1.2. 线程通讯方式 线程间通信常用方式如下 ...

最新文章

  1. Python之glob模块进行文件匹配及遍历
  2. DCMTK:“内容映射资源”Content Mapping Resource中的各种CIDxxx和TIDxxx类的测试程序
  3. 牛客 - 四等分的角度(几何)
  4. 1282:最大子矩阵《信息学奥赛一本通》
  5. java的resultset的next_java中resultset获取的是两个数据库,它的next()方法是怎么的
  6. 项目本地发布到github并且上线可预览
  7. 浏览器cookie那些事儿
  8. 分布式 NewSQL 数据库TiDB 3.1.0 版本发布,修复多项问题
  9. 求最大公约数的4种常用算法
  10. 3月6日服务器例行维护公告,热血江湖官方网站·系统公告
  11. android添加浮动组件,添加悬浮操作按钮  |  Android 开发者  |  Android Developers
  12. 分享四个一键生成神器:Logo、App、小程序、H5等五分钟快速搞定
  13. vue兼容IE 360
  14. onu光功率多少是正常_光猫的收发光功率正常范围是多少
  15. eclipse导入工程报错Faceted Project Problem(1 item)
  16. 音频接口简介(PDM/PCM/IIS/SLIMBUS)
  17. S*ST星美(000892):丰盛地产重组事宜形成初步方案
  18. 转:如何选择 Excel 中的数据列,然后将数据粘贴到文本文件中?
  19. 什么是温度传感器?温度传感器原理是什么?一文带你全部搞懂
  20. PyCharm提示 Backend Qt5Agg is interactive backend. Turning interactive mode on.

热门文章

  1. jpa怎么传参到in中_JPA 中 in 的方法 注意参数一定要是List
  2. .obj格式的文件怎么显示在html_怎么才能把安卓手机备忘录便签里的文件转到苹果上?...
  3. py获取前端的参数_Python小工具系列(3)之参数检查
  4. aliyun gradle 代理_gradle:现代高效的java构建工具
  5. 欢乐大作战服务器维护,欢乐大作战
  6. 侧信道攻击,从喊666到入门之——Unicorn的环境构建
  7. spring-页面模板配置
  8. 【数据结构】DFS 代码模板
  9. mysql创建存储过程及遍历查询结果,mysql 用存储过程遍历结果集
  10. vs 生成com组件 其他电脑_VS也可以这样进行快捷安装