栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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;

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);
  }
  
  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();
  }
  
  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();
    }
  }
  
  public void getResult(List> fList) {
    ExecutorService service = Executors.newSingleThreadExecutor();
    service.execute(getCollectJob(fList));
    service.shutdown();
  }
  
  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;
      }
    };
  }
  
  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();
    }
  }
  
  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 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多线程ForkJoinPool实例详解、Java通过卖票理解多线程、Java多线程之readwritelock读写分离的实现代码等,有什么问题可以随时留言,欢迎大家交流讨论。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/143844.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号