在Java编程中,有时候会需要及时获取线程的运行结果,本文就通过一个相关实例向大家介绍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<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>() { @Override public 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
下面是先执行完的线程先处理的方案:
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>() { @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及时获取多线程运行结果的实例分析的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SecLists
SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

PhpStorm Mac 版本
最新(2018.2.1 )专业的PHP集成开发工具

Atom编辑器mac版下载
最流行的的开源编辑器

ZendStudio 13.5.1 Mac
功能强大的PHP集成开发环境