java ExecutorService的invokeAll方法有两种用法 +价格超时计算

2023-05-16

exec.invokeAll(tasks)

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的返回值,每个任务要么正常地完成,要么被取消。

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

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();
        }
    }
 
}

执行结果:
耗时:3s,单价是:200.0,人数是:5,总额是:1000.00
耗时:3s,单价是:200.0,人数是:3,总额是:600.00
耗时:3s,单价是:200.0,人数是:7,总额是:1400.00
耗时:7s,单价是:200.0,人数是:4,总额是:800.00
耗时:4s,单价是:200.0,人数是:6,总额是:1200.00
耗时:1s,单价是:200.0,人数是:9,总额是:1800.00
耗时:10s,单价是:200.0,人数是:1,总额是:200.00
耗时:10s,单价是:200.0,人数是:2,总额是:400.00
耗时:3s,单价是:200.0,人数是:11,总额是:2200.00
耗时:4s,单价是:200.0,人数是:10,总额是:2000.00
耗时:2s,单价是:200.0,人数是:12,总额是:2400.00
耗时:6s,单价是:200.0,人数是:8,总额是:1600.00
耗时:3s,单价是:200.0,人数是:13,总额是:2600.00
耗时:2s,单价是:200.0,人数是:17,总额是:3400.00
任务超时,取消计算,单价是200.0,人数是:14
任务超时,取消计算,单价是200.0,人数是:15
任务超时,取消计算,单价是200.0,人数是:16
任务超时,取消计算,单价是200.0,人数是:18
任务超时,取消计算,单价是200.0,人数是:19
任务超时,取消计算,单价是200.0,人数是:20
200.00
400.00
600.00
800.00
1000.00
1200.00
1400.00
1600.00
1800.00
2000.00
2200.00
2400.00
2600.00
0
0
0
3400.00
0
0
0

Process finished with exit code 0

不控制超时时间期限

/**
 * 测试InvokeAll批量提交任务集
 * @throws InterruptedException 
 */
public  static void testInvokeAllThread() throws InterruptedException{
    ExecutorService exec = Executors.newFixedThreadPool(10);
 
    List<Callable<Integer>> tasks = new ArrayList<Callable<Integer>>();
    Callable<Integer> task = null;
    for (int i = 0; i < 20; i++) {
        task = new Callable<Integer>() {
            @Override
            public Integer call() throws Exception {
                int ran = new Random().nextInt(1000);
                Thread.sleep(ran);
                System.out.println(Thread.currentThread().getName()
                        + " 休息了 " + ran);
                return ran;
            }
        };
 
        tasks.add(task);
    }
 
    long s = System.currentTimeMillis();
    
    List<Future<Integer>> results = exec.invokeAll(tasks);
 
    System.out.println("执行任务消耗了 :" + (System.currentTimeMillis() - s)
            + "毫秒");
 
    for (int i = 0; i < results.size(); i++) {
        try {
            System.out.println(results.get(i).get());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    exec.shutdown();
}

执行结果
pool-2-thread-8 休息了 20
pool-2-thread-3 休息了 68
pool-2-thread-2 休息了 278
pool-2-thread-6 休息了 282
pool-2-thread-1 休息了 310
pool-2-thread-10 休息了 343
pool-2-thread-8 休息了 448
pool-2-thread-10 休息了 155
pool-2-thread-9 休息了 568
pool-2-thread-5 休息了 609
pool-2-thread-9 休息了 99
pool-2-thread-10 休息了 175
pool-2-thread-8 休息了 271
pool-2-thread-7 休息了 881
pool-2-thread-4 休息了 927
pool-2-thread-3 休息了 886
pool-2-thread-5 休息了 407
pool-2-thread-1 休息了 796
pool-2-thread-2 休息了 856
pool-2-thread-6 休息了 948
执行任务消耗了 :1232毫秒
310
278
68
927
609
282
881
20
568
343
448
886
856
948
796
155
271
175
99
407

Process finished with exit code 0
————————————————
版权声明:本文为CSDN博主「梦和远方」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_42614447/article/details/88682854

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java ExecutorService的invokeAll方法有两种用法 +价格超时计算 的相关文章

  • 在 Java 中克隆对象 [3 个问题]

    这样做会调用Asub的clone方法吗 或者Asub深度克隆是否正确 如果没有的话 有没有办法通过这种方法对Asub进行深度克隆呢 abstract class Top extends TopMost protected Object cl
  • Spring应用中Eureka健康检查的问题

    我正在开发一个基于 Spring 的应用程序 其中包含多个微服务 我的一个微服务充当尤里卡服务器 到目前为止一切正常 在我所有其他微服务中 用 EnableEurekaClient 我想启用这样的健康检查 应用程序 yml eureka c
  • 过滤两次 Lambda Java

    我有一个清单如下 1 2 3 4 5 6 7 和 预期结果必须是 1 2 3 4 5 6 7 我知道怎么做才能到7点 我的结果 1 2 3 4 5 6 我也想知道如何输入 7 我添加了i gt i objList size 1到我的过滤器
  • HSQL - 识别打开连接的数量

    我正在使用嵌入式 HSQL 数据库服务器 有什么方法可以识别活动打开连接的数量吗 Yes SELECT COUNT FROM INFORMATION SCHEMA SYSTEM SESSIONS
  • 如何在 Spring 中禁用使用 @Component 注释创建 bean?

    我的项目中有一些用于重构逻辑的通用接口 它看起来大约是这样的 public interface RefactorAwareEntryPoint default boolean doRefactor if EventLogService wa
  • 在接口中使用默认方法是否违反接口隔离原则?

    我正在学习 SOLID 原则 ISP 指出 客户端不应被迫依赖于他们所使用的接口 不使用 在接口中使用默认方法是否违反了这个原则 我见过类似的问题 但我在这里发布了一个示例 以便更清楚地了解我的示例是否违反了 ISP 假设我有这个例子 pu
  • Java 公历日历更改时区

    我正在尝试设置 HOUR OF DAY 字段并更改 GregorianCalendar 日期对象的时区 GregorianCalendar date new GregorianCalendar TimeZone getTimeZone GM
  • 从最终实体获取根证书和中间证书

    作为密码学的菜鸟 我每天都会偶然发现一些简单的事情 今天只是那些日子之一 我想用 bouncy castle 库验证 java 中的 smime 消息 我想我几乎已经弄清楚了 但此时的问题是 PKIXparameters 对象的构建 假设我
  • 将流转换为 IntStream

    我有一种感觉 我在这里错过了一些东西 我发现自己做了以下事情 private static int getHighestValue Map
  • 将 MOXy 设置为 JAXB 提供程序,而在同一包中没有属性文件

    我正在尝试使用 MOXy 作为我的 JAXB 提供程序 以便将内容编组 解组到 XML JSON 中 我创建了 jaxb properties 文件 内容如下 javax xml bind context factory org eclip
  • Java ResultSet 如何检查是否有结果

    结果集 http java sun com j2se 1 4 2 docs api java sql ResultSet html没有 hasNext 方法 我想检查 resultSet 是否有任何值 这是正确的方法吗 if resultS
  • 如何访问JAR文件中的Maven资源? [复制]

    这个问题在这里已经有答案了 我有一个使用 Maven 构建的 Java 应用程序 我有一个资源文件夹com pkg resources 我需要从中访问文件 例如directory txt 我一直在查看各种教程和其他答案 但似乎没有一个对我有
  • 尝试将 Web 服务部署到 TomEE 时出现“找不到...的 appInfo”

    我有一个非常简单的项目 用于培训目的 它是一个 RESTful Web 服务 我使用 js css 和 html 创建了一个客户端 我正在尝试将该服务部署到 TomEE 这是我尝试部署时遇到的错误 我在这里做错了什么 刚刚遇到这个问题 我曾
  • Eclipse 选项卡宽度不变

    我浏览了一些与此相关的帖子 但它们似乎并不能帮助我解决我的问题 我有一个项目 其中 java 文件以 2 个空格的宽度缩进 我想将所有内容更改为 4 空格宽度 我尝试了 正确的缩进 选项 但当我将几行修改为 4 空格缩进时 它只是将所有内容
  • 不接受任何内容也不返回任何内容的函数接口[重复]

    这个问题在这里已经有答案了 JDK中是否有一个标准的函数式接口 不接受也不返回任何内容 我找不到一个 像下面这样 FunctionalInterface interface Action void execute 可运行怎么样 Functi
  • 最新的 Hibernate 和 Derby:无法建立 JDBC 连接

    我正在尝试创建一个使用 Hibernate 连接到 Derby 数据库的准系统项目 我正在使用 Hibernate 和 Derby 的最新版本 但我得到的是通用的Unable to make JDBC Connection error 这是
  • Eclipse 启动时崩溃;退出代码=13

    I am trying to work with Eclipse Helios on my x64 machine Im pretty sure now that this problem could occur with any ecli
  • Opencv Java 灰度

    我编写了以下程序 尝试从彩色转换为灰度 Mat newImage Imgcodecs imread q1 jpg Mat image new Mat new Size newImage cols newImage rows CvType C
  • 双枢轴快速排序和快速排序有什么区别?

    我以前从未见过双枢轴快速排序 是快速排序的升级版吗 双枢轴快速排序和快速排序有什么区别 我在 Java 文档中找到了这个 排序算法是双枢轴快速排序 作者 弗拉基米尔 雅罗斯拉夫斯基 乔恩 本特利和约书亚 布洛赫 这个算法 在许多数据集上提供
  • Java中super关键字的范围和使用

    为什么无法使用 super 关键字访问父类变量 使用以下代码 输出为 feline cougar c c class Feline public String type f public Feline System out print fe

随机推荐

  • 求解最大连通子图

    使用networkx里面的函数来求解最大连通子图 coding utf 8 34 34 34 Created on Wed Mar 11 21 38 53 2020 64 author Administrator 34 34 34 impo
  • Result Maps collection already contains value for BaseResultMap

    由于mybatis简单易学 xff0c 比起Hibername来 xff0c 更容易上手 xff0c 代码也能自动生成 这几天研究了下代码自动生成的 xff0c 参考 xff1a http 0609xiaohua iteye com blo
  • ssm测试mybatis时出现无法连接数据库驱动的错误

    org apache ibatis exceptions PersistenceException Error querying database Cause org springframework jdbc CannotGetJdbcCo
  • 表白密码:I Love you的42种密码表白方式

    字母表白数字密码 xff1a 9121522521 表白解密 xff1a 从1开始到26 xff0c 分别表示从A到Z xff0c 即 xff1a A xff08 1 xff09 B xff08 2 xff09 C xff08 3 xff0
  • 【电脑系统】c盘误操作删除EFI引导分区后,开机一直checking media

    目录 一 问题描述二 问题解决 一 问题描述 1 利用分区工具不小心将c盘中ESP分区和MSR分区合并了 xff0c 开机后一直checking media 2 用u盘装系统 xff0c 进入pe后还原重装系统后 xff0c 开机仍然是ch
  • 【面试】spring中ioc加载过程

    目录 一 加载过程1 概念态 gt 定义态2 定义态 gt 纯净态3 纯净态 gt 成熟态4 初始化5 创建完成 一 加载过程 1 概念态 gt 定义态 1 实例化一个ApplicationContext的对象 2 调用bean工厂后置处理
  • 【spring】spring有哪几种配置方式

    目录 一 说明二 配置方式三 配置示例3 1 基于xml配置文件3 2 基于注解的配置3 3 基于java的配置 一 说明 1 spring有三种重要的方法提供配置元数据 二 配置方式 1 基于xml配置文件 xff0c spring诞生的
  • 远程登录Windows的WSL子系统

    很多文章要么只有安装 wsl 和 ssh xff0c 要么只有设置端口转发 xff0c 完全不能一篇文章解决标题中的问题 由于最近不在办公室 xff0c 需要远程登录办公室的电脑 xff0c 这样可以节省很多时间去配置各种命令 回归正题 x
  • curl: (1) Protocol "'http" not supported or disabled in libcurl异常

    笔者在window中安装了curl 但是在使用过程中出现了错误 xff01 curl 1 Protocol 34 39 http 34 not supported or disabled in libcurl 最后经过排查 xff0c 发现
  • 获奖公布 | 征文——从高考到程序员

    每年的这几天 xff0c 空气中总会弥漫着紧张的味道 xff0c 2017 全国统一高考如期而至 朋友圈里的各种高考热文如流水般 xff0c 不停歇地出现在眼前 xff0c 难免会勾起自己曾经的青涩时光 还记得 xff0c 考试前 xff0
  • 消息队列

    一 什么是消息队列 我们可以把消息队列比作是一个存放消息的容器 xff0c 当我们需要使用消息的时候可以取出消息供自己使用 消息队列是分布式系统中重要的组件 xff0c 使用消息队列主要是为了通过异步处理提高系统性能和削峰 降低系统耦合性
  • ubuntu开机自启动(绝对好用)

    linux服务管理有两种方式service和systemctl lib systemd system 和 etc systemd system 存放所有可用的单元文件 systemctl test service start 比如需要开机启
  • networkx教程

    创建一个图 创建一个没有节点和边的空图 import networkx as nx G 61 nx Graph 根据定义 xff0c a span class pre Graph span 是节点 xff08 顶点 xff09 的集合以及确
  • java.lang.IllegalStateException异常产生的原因及解决办法

    错误类型大致为以下几种 xff1a java lang IllegalStateException xff1a Cannot forward a response that is already committed IllegalState
  • android测试:unresolved reference AndroidJUnit4

    如上 xff0c 如果你的测试文件在上面这个目录下 将依赖改为 androidTestImplementatio开始即可
  • hexo 绑定自己的域名

    前提 xff0c 你得有一个域名 xff0c 有些域名需要备案后才能用 在域名解析添加记录 如果你用你顶点域名 xff08 如 xff1a lookk cn xff0c 就添加一条主机记录为 64 的 xff0c 如果你用www子域名 xf
  • java 把List集合转换为json

    1 servlet List转json 需要jar包 xff0c 可以到我github下载 commons beanutils 1 7 0 jar commons collections 3 2 jar commons httpclient
  • Manjaro Gnome版设置默认文件管理器(inode/directory)为Nautilus

    自从安装Visual Studio Code以后不知道为什么默认的文件管理器会被改为这个玩意 xff0c 每次像打开应用程序目录这样的操作弹出的都是VS Code xff0c 而且仅仅显示上次使用VS Code时的会话 xff0c 并不会显
  • 在linux下安装redis集群的踩坑记录

    这里是引用 这里写自定义目录标题 环境软件及说明安装集群心得最新安装的redisredis conf 中bind 属性需要重新配置的情况Can I set the above configuration还是历史数据问题redis 密码相关
  • java ExecutorService的invokeAll方法有两种用法 +价格超时计算

    exec invokeAll tasks exec invokeAll tasks timeout unit 其中tasks是任务集合 xff0c timeout是超时时间 xff0c unit是时间单位 两者都会堵塞 xff0c 必须等待