深入学习理解 1 java ExecutorService invokeAll 任务的批量提交invokeAll两种方

                       

ExecutorService的invokeAll方法有两种用法:

1.exec.invokeAll(tasks)

2.exec.invokeAll(tasks, timeout, unit)

其中tasks是任务集合,timeout是超时时间,unit是时间单位

两者都会堵塞,必须等待所有的任务执行完成后统一返回,一方面内存持有的时间长;另一方面响应性也有一定的影响,毕竟大家都喜欢看看刷刷的执行结果输出,而不是苦苦的等待;

但是方法二增加了超时时间控制,这里的超时时间是针对的所有tasks,而不是单个task的超时时间。如果超时,会取消没有执行完的所有任务,并抛出超时异常。相当于将每一个future的执行情况用一个list集合保存,当调用future.get()方法取值时和设置的timeout比较,是否超时。

InvokeAll方法处理一个任务的容器(collection),并返回一个Future的容器。两个容器具有相同的结构;

这里提交的任务容器列表和返回的Future列表存在顺序对应的关系。

invokeAll将Future添加到返回容器中,这样可以使用任务容器的迭代器,从而调用者可以将它表现的Callable与Future关联起来。

当所有任务都完成时、调用线程被中断时或者超过时限时,限时版本的invokeAll都会返回结果。超过时限后,任何尚未完成的任务都会被取消。

作为invokeAll的返回值,每个任务要么正常地完成,要么被取消。

invokeAll控制批量任务的时间期限的例子:

package com.thread;import java.math.BigDecimal;import java.sql.Time;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Random;import java.util.concurrent.Callable;import java.util.concurrent.CancellationException;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.TimeUnit;/** * 批量任务的限时 invokeAll(tasks) 批量提交不限时任务 *  * invokeAll(tasks, timeout, unit) 批量提交限时任务 *  * InvokeAll方法处理一个任务的容器(collection),并返回一个Future的容器。两个容器具有相同的结构: * invokeAll将Future添加到返回的容器中,这样可以使用任务容器的迭代器,从而调用者可以将它表现的Callable与Future 关联起来。 * 当所有任务都完成时、调用线程被中断时或者超过时限时,限时版本的invokeAll都会返回结果。 超过时限后,任务尚未完成的任务都会被取消。 *  * @author hadoop * */public class InvokeAllThread { // 固定大小的线程池,同时只能接受5个任务 static ExecutorService mExecutor = Executors.newFixedThreadPool(5); /**  * 计算价格的任务  * @author hadoop  *  */ private class QuoteTask implements Callable<BigDecimal> {  public final double price;  public final int num;  public QuoteTask(double price, int num) {   this.price = price;   this.num = num;  }  @Override  public BigDecimal call() throws Exception {   Random r = new Random();   long time = (r.nextInt(10) + 1) * 1000;   Thread.sleep(time);   BigDecimal d = BigDecimal.valueOf(price * num).setScale(2);   System.out.println("耗时:" + time / 1000 + "s,单价是:" + price + ",人数是:"     + num + ",总额是:" + d);   return d;  } } /**  * 在预定时间内请求获得旅游报价信息  *   * @return  */ public   void getRankedTravelQuotes() throws InterruptedException {  List<QuoteTask> tasks = new ArrayList<QuoteTask>();  // 模拟10个计算旅游报价的任务  for (int i = 1; i <= 20; i++) {   tasks.add(new QuoteTask(200, i) );  }  /**   * 使用invokeAll方法批量提交限时任务任务 预期15s所有任务都执行完,没有执行完的任务会自动取消   *    */     List<Future<BigDecimal>> futures = mExecutor.invokeAll(tasks, 15, TimeUnit.SECONDS);  // 报价合计集合  List<BigDecimal> totalPriceList = new ArrayList<BigDecimal>();  Iterator<QuoteTask> taskIter = tasks.iterator();  for (Future<BigDecimal> future : futures) {    QuoteTask task = taskIter.next();   try {    totalPriceList.add(future.get());   } catch (ExecutionException e) {    // 返回计算失败的原因    // totalPriceList.add(task.getFailureQuote(e.getCause()));    totalPriceList.add(BigDecimal.valueOf(-1));     System.out.println("任务执行异常,单价是"+task.price+",人数是:"+task.num);   } catch (CancellationException e) {    // totalPriceList.add(task.getTimeoutQuote(e));    totalPriceList.add(BigDecimal.ZERO);     System.out.println("任务超时,取消计算,单价是"+task.price+",人数是:"+task.num);   }  }  for (BigDecimal bigDecimal : totalPriceList) {   System.out.println(bigDecimal);  }  mExecutor.shutdown(); }  public static void main(String[] args) {  try {   InvokeAllThread it = new InvokeAllThread();   it.getRankedTravelQuotes();  } catch (InterruptedException e) {   // TODO Auto-generated catch block   e.printStackTrace();  } }}
   
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
           

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自blog.csdn.net/qq_43746757/article/details/86070593