Java 并发编程学习笔记(16) ----CompletionService

25 | CompletionService:如何批量执行异步任务? 本文介绍了如何利用Java并发工具类CompletionService优化异步任务批处理。通过对比传统"ThreadPoolExecutor+Future"方案的阻塞问题,提出使用阻塞队列实现任务按完成顺序处理的方案。重点讲解了CompletionService的工作原理和优势,其内部维护阻塞队列来管理任务执行结果的Future对象。文章通过询价系统示例展示了CompletionService的实际应用,包括创建方法、任务提交和结果获取。最后还介绍了如何利用CompletionService实现Dubbo的 阅读详情

CompletionService

1.1 CompletionService 的功能

CompletionService的功能就是以异步的方式,一边产生新的任务,一边处理已完成任务的结果。 
CompletionService主要解决一个什么问题呢? 
    Future 接口调用get()方法取得处理的结果,但是这个方法是阻塞性的,如果调用get()
方法时,任务尚未执行完成,get方法会一直阻塞到此任务执行完成为止。这样的后果就是一旦前面
的任务耗时太长,后面的任务的get()方法就会排队等待,影响相率。
    使用CompletionService可以按照完成这些任务的时间顺序处理他们的结果。

1.2 代码


package com.lhc.concurrent.completion.nonBlock;

import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.concurrent.*;

public class MyCallable implements Callable<String>{
    private String userName;
    private long sleepTime;

    public MyCallable(String userName, long sleepTime) {
        this.userName = userName;
        this.sleepTime = sleepTime;
    }

    @Override
    public String call() throws Exception {
        System.out.println(userName);
        Thread.sleep(sleepTime);
        return "return " + sleepTime;
    }

    public static void main(String[] args) throws Exception{
        MyCallable name1 = new MyCallable("name1", 1050);
        MyCallable name2 = new MyCallable("name2", 1040);
        MyCallable name3 = new MyCallable("name3", 1030);
        MyCallable name4 = new MyCallable("name4", 1020);
        MyCallable name5 = new MyCallable("name5", 1010);

        ArrayList<Callable> callables = Lists.newArrayList();
        callables.add(name1);
        callables.add(name2);
        callables.add(name3);
        callables.add(name4);
        callables.add(name5);

        ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 5,
                TimeUnit.SECONDS, new LinkedBlockingDeque<Runnable>());
        ExecutorCompletionService completionService = new ExecutorCompletionService(executor);

        for (int i = 0; i < callables.size(); i++) {
            completionService.submit(callables.get(i));
        }

        for (int i = 0; i < 5; i++){
            /**
             * 哪个任务先执行完,那个任务的返回值就先打印,解决了Future 阻塞的特点
             * 但是如果没有任何任务被执行完,则.take().get()方法还是呈阻塞特性。
             */
            System.out.println(completionService.take().get());
        }
    }
}

1.3测试结果

name1
name5
name2
name3
name4
return 1010
return 1020
return 1030
return 1040
return 1050

2.1 Future submit(Runnable task, V result)方法

另外一种使用姿势

2.2 代码


public class User {
    private String name;
    private String password;

    public User(String name, String password) {
        super();
        this.name = name;
        this.password = password;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}


package com.lhc.concurrent.completion.submit;

import java.util.concurrent.*;

public class MyRunnable implements Runnable{
    private User user;

    public MyRunnable(User user) {
        super();
        this.user = user;
    }

    @Override
    public void run() {
        user.setName("jt");
        user.setPassword("pwd");
        System.out.println("running end");
    }

    public static void main(String[] args) throws Exception{
        User user = new User("name", "pwd");
        MyRunnable myRunnable = new MyRunnable(user);

        ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorCompletionService completionService = new ExecutorCompletionService(executorService);
        Future<User> submit = completionService.submit(myRunnable, user);
        System.out.println(submit.get().getName() + " " + submit.get().getPassword());
    }
}


2.3 运行结果

running end
jt pwd

LabVIEW多界面应用开发:从启动器到主界面的切换架构与实现 在图形化编程领域,模块化与界面管理是构建复杂应用程序的核心。其原理在于通过清晰的程序架构,实现不同功能模块间的独立运行与协同工作,从而提升代码的可维护性和可扩展性。这种架构的技术价值在于能够有效管理应用程序的生命周期与资源,避免内存泄漏,并确保流畅的用户体验。在测控系统、自动化测试等工程实践中,常需实现如启动界面选择语言或模式后,无缝切换至主功能界面的场景。本文聚焦于LabVIEW环境,深入探讨如何利用动态调用、状态机等机制,并结合功能全局变量(FGV)与队列消息处理器(QMH)等热词技术,构建健壮的多界面 阅读详情

相关推荐

AI驱动的CNC闭环加工系统:边缘实时控制与IIoT反馈实践

闭环控制是工业自动化的核心概念,指通过实时反馈调节系统输出以逼近目标值;其技术原理在于构建短于被控对象时间常数的确定性反馈链路,从而保障动态响应精度与稳定性。在智能制造落地中,AI正从离线分析工具演进为嵌入式实时决策单元,其核心价值在于将工艺知识模型化、控制指令轻量化、执行路径边缘化。典型应用场景包括CNC加工过程中的振动自适应调参、刀具磨损在线补偿及多机协同优化。本实践聚焦FANUC 0i-MF平台,基于Modbus TCP硬实时通信与轻量LSTM+CNN融合模型,实现217毫秒级AI推理与PMC寄存器直

weixin_29704001的博客 323

java多线程:CompletionService的使用

1.CompletionService是什么? 答 :CompletionService的功能是以异步的方式,一边产生新任务,一边处理已完成的任务的结果,这样可以将执行任务与处理任务分开来处理。使用submit来执行任务,使用take来取得已完成的任务,并按照完成这些任务的时间顺序处理完成的任务。该接口其实与future的功能相似,但是与future的最大不同在于future必须要等待所有的...

zhaoliubao1的博客 636

凌欧通用FOC框架解析(5.程序环流程)

结构体:电流内环.这是一个结构体函数占空比13.

weixin_43756295的博客 2931

java: CompletionService的使用

java

amadeus_liu2的博客 299

基于SHIS凝视型短波红外高光谱相机(900-1700nm)区分不同宝石的差异性和可分性(宝石分选)

SHIS系列凝视型高光谱相机基于液晶可调谐滤波器(LCTF),通过电控LCTF进行连续细分窄波段分光,对每个波段进行高分辨率的二维面阵成像,进行图像处理后,获得完整的高光谱高清图像序列。具有低功耗、小型化、使用方便和易于扩展的优势。其工作波段覆盖400nm至1000nm,能够捕捉宝石在不同波长下的光谱特征,为宝石鉴定提供了新的工具。

wayho的博客 707

Springer期刊LaTeX模板中参考文献格式选择与编译错误的快速修复指南

本文针对Springer期刊LaTeX模板中参考文献编译后显示问号的常见问题,提供了快速修复指南。核心在于正确选择并配置与期刊匹配的参考文献格式文件(.bst),并执行标准的四步编译流程。文章详细解释了问题根源,并给出了从查找正确.bst文件到修改代码、执行编译的完整解决方案,帮助作者高效解决投稿中的技术障碍。

weixin_29266007的博客 401

completionService.submit和CompletableFuture.runAsync方法讲解

这行代码中,我们使用CompletableFuture.runAsync()创建了一个异步任务,并将其提交给CompletionService进行执行。然后,我们可以通过调用future.get()获取任务的结果,这里的结果是我们之前传入的优先级值。在这个示例代码中,我们使用了CompletionService来提交和获取已完成的任务。通过ExecutorCompletionService的构造函数,我们将一个已有的ExecutorService传入CompletionService中。

还在活水泥的未来包工头 668

OpenClaw实战系列01:OpenClaw接入飞书机器人全接入指南 + Ollama本地大模型

通过 OpenClaw + Ollama + 飞书的组合,我们成功搭建了一个完全私有、免费、可定制的AI助理。它不仅能在日常聊天中提供帮助,还能通过OpenClaw强大的“技能”体系,真正去操作你的电脑、管理文件、甚至执行代码。这套方案将数据留在本地,既保证了隐私安全,又锻炼了动手能力。现在,去给你的AI助理添加更多酷炫的技能吧!

PeterPan的博客 1万+

了解一下CompletionService的submit(Runnable task, V result)方法

示例demo: public class CompletionServiceDemo { public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService pool = Executors.newFixedThreadPool(3); ExecutorCompletionService<String> comp.

硅脂味咖啡的博客 2423

9篇2章2节:GBD 数据库的数据申请详解

无论您是初入公共卫生领域的学生、资深的科研工作者,还是政策决策者,GBD数据库都将成为您数据分析与决策支持中不可或缺的重要工具。

MD Code 2599

从工具选型到落地实践:吃透 SAP Fiori Launchpad 配置工具体系

摘要: SAP Fiori Launchpad配置远非简单添加应用和分配角色,涉及技术目录、业务目录、Spaces/Pages等多层管理。官方推荐新工具分工:技术目录用FLPAM维护应用定义,业务目录用FLPCM编排应用组合,Spaces/Pages优化用户体验布局,而传统Groups模式已被标记弃用。这种分层治理模式(定义层-编排层-展示层)能有效解决传输混乱、升级兼容性问题,尤其适合大规模项目实施。关键在于区分技术配置与业务呈现,避免将所有功能堆砌在单一旧工具中。(149字)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 103

Thread之CompletionService的使用

CompletionService的简单使用 使用submit()方法执行任务,使用take取得已完成的任务,并按照完成这些任务的时间顺序处理它们的结果。 一、CompletionService的submit方法 /** * @author wzx * @time 2018/2/8 */ public class CompletionServiceTest { public s...

wang704987562的博客 946

实战|2026美团&大众点评餐饮数据抓取:Playwright/Selenium反爬全攻略

核心结论:2026年美团&大众点评的反爬核心是“多维度风控”,需组合使用“住宅IP+设备指纹伪装+真人行为模拟+动态验证处理”,Playwright是最优工具,Selenium仅作为补充。效率优化:单机爬取速度建议控制在“每小时500-800条”,避免高频请求触发风控;分布式爬取需确保每个节点使用独立住宅IP,且行为轨迹不一致。扩展方向集成WASM解密工具,破解2026年美团的Token加密;用AI识别动态点选验证,提升验证通过率;对接大数据平台,对抓取的餐饮数据进行可视化分析。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2461

Java并发编程系列之二十八:CompletionService

CompletionService简介CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而CompletionService则是一个接口,那么为什么CompletionService不直接继承Executor接口呢?主要是Executor的特性决定的,Executor框架不能完全保证任务执行的异

rhwayfun专栏 1万+

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

并发编程 06—— CompletionService :Executor 和 BlockingQueue

Java并发编程实践 目录 并发编程 01—— ThreadLocal 并发编程 02—— ConcurrentHashMap 并发编程 03—— 阻塞队列和生产者-消费者模式 并发编程 04—— 闭锁CountDownLatch 与 栅栏CyclicBarrier 并发编程 05—— Callable和Future 并发编程 06—— CompletionService : Exec...

LMAKE_nbsp的博客 297

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

并发编程十六:Future、CompletionService、CompletableFuture和Disruptor队列实战

文章目录Future、CompletionService、CompletableFuture和Disruptor队列实战Future案例CompletionService案例CompletionService原理应用场景CompletableFuture应用场景案例依赖关系案例and聚合关系or聚合关系异常处理CompletableFuture常用方法总结高性能队列Disruptor简介数据结构Disruptor核心概念Disruptor的使用案例 Future、CompletionService、Comp

admin522043032的博客 1272

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java并发基础:CompletionService全面解析!

CompletionService的优点在于能够解耦任务提交与结果获取,有效的整合线程池与阻塞队列,实现任务完成顺序的处理,提升系统吞吐量,它简化了多线程编程的复杂性,使开发者能够更专注于业务逻辑,而不必过多关注线程管理细节。

科技互联网领域深度探索者,乐于分享与写作。 1381

Java并发编程:CompletionService

CompletionService简介 CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而CompletionService则是一个接口,那么为什么CompletionService不直接继承Executor接口呢?主要是Executor的特性决定的,Executor框架不能完全保证任务执

xiangcaoyihan的专栏 266

Java中ExecutorService和CompletionService区别

我们现在在Java中使用多线程通常不会直接用Thread对象了,而是会用到java.util.concurrent包下的ExecutorService类来初始化一个线程池供我们使用。 之前我一直习惯自己维护一个list保存submit的callable task所返回的Future对象。 在主线程中遍历这个list并调用Future的get()方法取到Task的返回值。  

somilong的博客 1075

CompletionService简介、原理以及小案例

博客1:http://www.oschina.net/question/12_11255博客2:CompletionService简介CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而CompletionService则是一个接口,那么为什么CompletionService不直接继承Exe...

LZJWXJ树袋熊 2万+

CompletionService 介绍

原文链接:https://blog.csdn.net/u011116672/article/details/51113769CompletionService简介CompletionService与ExecutorService类似都可以用来执行线程池的任务,ExecutorService继承了Executor接口,而CompletionService则是一个接口,那么为什么CompletionS...

AJ1101的博客 321

[Java并发-16] CompletionService:批量执行异步任务

我们思考下这个场景:从三个电商询价,然后保存在自己的数据库里。通过之前所学,我们可能这么实现。 // 创建线程池 ExecutorService executor = Executors.newFixedThreadPool(3); // 异步向电商 S1 询价 Future<Integer> f1 = executor.submit( ()->getPric...

df007df的博客 206

Java 并发编程实战

并发编程是现代软件开发的核心技能,其本质可归纳为三个关键问题:分工、同步和互斥。分工关注如何高效分配任务给线程;同步解决线程间的协作问题;互斥确保共享资源的安全访问。学习并发编程需要"跳出来看全景"建立知识体系,同时"钻进去看本质"理解底层理论模型。Java SDK提供的并发工具如Executor、Future、锁机制等,都是对这些核心问题的解决方案。掌握这些概念不仅能提升程序性能,更能保障多线程环境下的正确性。建议学习者通过思维导图梳理知识脉络,并结合实际场景深入理解管程、内存模型等基础理论。

刘大猫 2084

并发编程十四:Future、CompletionService、CompletableFuture和Disruptor队列实战

并发编程十四:Future、CompletionService、CompletableFuture和Disruptor队列实战

huaxinzhang的博客 251

使用CompletionService结合ExecutorService批处理任务

CompletionService用于提交一组Callable任务,其take方法返回已完成的一个Callable任务对应的Future对象。 如果你向Executor提交了一个批处理任务,并且希望在它们完成后获得结果。为此你可以将每个任务的Future保存进一个集合,然后循环这个集合调用Future的get()取出数据。幸运的是CompletionService帮你做了这件事情。 Compl

tyfbhlxd的博客 262
上一篇: Java 并发编程学习笔记(15) ----Future 和 Callable
下一篇: 了解红黑树
过河的小卒子
博客等级 码龄10年 39粉丝 112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值