数码控科技猎奇Iphone动漫星座游戏电竞lolcosplay王者荣耀攻略allcnewsBLOGNEWSBLOGASKBLOGBLOGZSK全部技术问答问答技术问答it问答代码软件新闻开发博客电脑/网络手机/数码笔记本电脑互联网操作系统软件硬件编程开发360产品资源分享电脑知识文档中心IT全部全部分类全部分类技术牛文全部分类教程最新网页制作cms教程平面设计媒体动画操作系统网站运营网络安全服务器教程数据库工具网络安全软件教学vbscript正则表达式javascript批处理更多»编程更新教程更新游戏更新allitnewsJava新闻网络医疗信息化安全创业站长电商科技访谈域名会议专栏创业动态融资创投创业学院 / 产品经理创业公司人物访谈营销开发数据库服务器系统虚拟化云计算嵌入式移动开发作业作业1常见软件all电脑网络手机数码生活游戏体育运动明星影音休闲爱好文化艺术社会民生教育科学医疗健康金融管理情感社交地区其他电脑互联网软件硬件编程开发360相关产品手机平板其他电子产品摄影器材360硬件通讯智能设备购物时尚生活常识美容塑身服装服饰出行旅游交通汽车购房置业家居装修美食烹饪单机电脑游戏网页游戏电视游戏桌游棋牌游戏手机游戏小游戏掌机游戏客户端游戏集体游戏其他游戏体育赛事篮球足球其他运动球类运动赛车健身运动运动用品影视娱乐人物音乐动漫摄影摄像收藏宠物幽默搞笑起名花鸟鱼虫茶艺彩票星座占卜书画美术舞蹈小说图书器乐声乐小品相声戏剧戏曲手工艺品历史话题时事政治就业职场军事国防节日风俗法律法规宗教礼仪礼节自然灾害360维权社会人物升学入学人文社科外语资格考试公务员留学出国家庭教育学习方法语文物理生物工程学农业数学化学健康知识心理健康孕育早教内科外科妇产科儿科皮肤科五官科男科整形中医药品传染科其他疾病医院两性肿瘤科创业投资企业管理财务税务银行股票金融理财基金债券保险贸易商务文书国民经济爱情婚姻家庭烦恼北京上海重庆天津黑龙江吉林辽宁河北内蒙古山西陕西宁夏甘肃青海新疆西藏四川贵州云南河南湖北湖南山东江苏浙江安徽江西福建广东广西海南香港澳门台湾海外地区

Java利用future及时获取多线程运行结果

来源:脚本之家  责任编辑:小易  时间:2018/1/26 20:25:55

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及时获取线程运行结果的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:Java多线程ForkJoinPool实例详解Java通过卖票理解多线程Java多线程之readwritelock读写分离的实现代码等,有什么问题可以随时留言,欢迎大家交流讨论。

您可能感兴趣的文章:


  • 本文相关:
  • java多线程之readwritelock读写分离的实现代码
  • 浅谈java多线程处理中future的妙用(附源码)
  • java多线程之死锁的出现和解决方法
  • java多线程编程实现socket通信示例代码
  • java多线程之线程通信生产者消费者模式及等待唤醒机制代码详解
  • java多线程编程实例
  • java多线程之显示锁和内置锁总结详解
  • java多线程之线程,进程和synchronized概念初解
  • java 中 zookeeper简单使用
  • zookeeper
  • 使用
  • java反射机制实例教程
  • java
  • 反射机制
  • java equals和==的区别详解
  • java
  • equals和==
  • 区别
  • java使用泛型实现栈结构示例分享
  • java
  • 泛型
  • java md5加密实现代码
  • java
  • md5
  • 加密
  • 理解java中的内存泄露及解决方法示例
  • java
  • 内存泄露
  • 解决方法
  • java解析xml格式数据的方法详解
  • java
  • xml
  • java 判断字符串a和b是否互为旋转词
  • 旋转
  • 详解java的位操作符
  • java
  • 操作符
  • 最值得java开发者收藏的网站
  • java
  • 开发
  • 网站
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved