当前位置: 首页 > article >正文

孤舟笔记 并发篇二十四 线程池如何知道一个线程的任务已经执行完成?三种方式各有乾坤

文章目录一、先说结论感知任务完成的三种方式二、方式一Future.get()三、方式二CompletionService四、方式三CountDownLatch五、方式四FutureTask 回调六、对比总结感知任务完成方式全景回答技巧与点评标准回答加分回答面试官点评个人网站你提交了一堆任务到线程池想等它们全部完成再往下走怎么搞或者你想知道某个任务执行完了没有拿没拿到结果这些场景都涉及线程池怎么感知任务完成。面试官问这个问题不只是考 API更是考你对 Future、CompletionService 这些工具的理解深度。一、先说结论感知任务完成的三种方式方式适用场景特点Future.get()等待单个任务完成阻塞等待可获取结果CompletionService批量任务按完成顺序获取先完成的先拿到CountDownLatch批量任务等待全部完成不关心结果只等全部做完invokeAll()批量任务等待全部完成返回所有 FutureisTerminated()线程池关闭后判断需先 shutdown()一句话记住单个任务用 Future批量按序用 CompletionService批量等完用 CountDownLatch——工具选对事半功倍。二、方式一Future.get()最基本的方式——提交任务时拿到 Future调用 get() 阻塞等待ExecutorServicepoolExecutors.newFixedThreadPool(3);FutureStringfuturepool.submit(()-{Thread.sleep(2000);return任务结果;});// 阻塞等待直到任务完成Stringresultfuture.get();// 最多等多久一直等System.out.println(result);// 带超时的等待Stringresult2future.get(5,TimeUnit.SECONDS);// 5秒超时问题如果提交了多个任务逐个 get() 是串行等待的ListFutureStringfuturesnewArrayList();for(inti0;i5;i){futures.add(pool.submit(()-doTask()));}// ❌ 问题如果第一个任务最慢后面快的也得等for(FutureStringf:futures){System.out.println(f.get());// 串行阻塞 }生活类比你去医院取五个检查报告挨个窗口等——哪怕第二个报告早出了你也得先等第一个。三、方式二CompletionServiceCompletionService 解决了串行等待的问题——谁先完成谁先拿到ExecutorServicepoolExecutors.newFixedThreadPool(3);CompletionServiceStringcsnewExecutorCompletionService(pool);// 提交 5 个任务for(inti0;i5;i){finalintidxi;cs.submit(()-doTask(idx));}// 按完成顺序获取结果for(inti0;i5;i){FutureStringfcs.take();// 取一个已完成的 Future阻塞System.out.println(f.get());// 立刻获取结果不阻塞}原理CompletionService 内部维护了一个BlockingQueueFuture任务完成后 Future 自动入队。take() 从队列取谁先完成谁先进队列。生活类比五个人同时做饭谁先做好谁先端上来——不用等最慢的那道菜。经典应用从多个搜索引擎取结果谁先返回就用谁CompletionServiceStringcsnewExecutorCompletionService(pool);cs.submit(()-searchBaidu(keyword));cs.submit(()-searchGoogle(keyword));cs.submit(()-searchBing(keyword));// 谁先返回就用谁Stringresultcs.take().get();四、方式三CountDownLatch如果你不关心结果只关心全部做完用 CountDownLatchinttaskCount10;CountDownLatchlatchnewCountDownLatch(taskCount);for(inti0;itaskCount;i){pool.submit(()-{try{doTask();}finally{latch.countDown();// 每完成一个计数器 -1}});}latch.await();// 阻塞等待直到计数器归零System.out.println(所有任务执行完毕);生活类比10 个工人在干活你在大门口数人头——最后一个回来了关门下班。vs invokeAll()// invokeAll 也能等全部完成ListFutureStringfuturespool.invokeAll(tasks);// 阻塞等所有任务完成for(FutureStringf:futures){System.out.println(f.get());}区别invokeAll 返回所有 Future可以拿结果CountDownLatch 更轻量只做同步。五、方式四FutureTask 回调Java 8 可以用 CompletableFuture 实现回调式通知CompletableFuture.supplyAsync(()-doTask(),pool).thenAccept(result-{System.out.println(任务完成结果: result);// 回调不阻塞});// 主线程继续做其他事...优势不阻塞等待任务完成后自动回调。这是最现代的方式。六、对比总结方式阻塞获取结果批量按序Future.get()阻塞✅❌ 串行等CompletionService阻塞✅✅ 先完成先取CountDownLatch阻塞❌等全部完成invokeAll()阻塞✅等全部完成CompletableFuture非阻塞回调✅✅ 任意组合感知任务完成方式全景感知任务完成 全景 单个任务 └── Future.get() ── 阻塞等待结果 批量任务 ├── CompletionService ── 按完成顺序取先完先得 ├── CountDownLatch ── 只等全部完成不管结果 ├── invokeAll() ── 等全部完成返回所有 Future └── CompletableFuture ── 回调式非阻塞 选择策略 ├── 要结果、单个任务 → Future.get() ├── 要结果、批量按序 → CompletionService ├── 不要结果、只等完成 → CountDownLatch └── 不想阻塞 → CompletableFuture 口诀Future 等单个Completion 按序取 Latch 等全部Completable 回调走 阻塞非阻塞各有所长场景选对是关键。回答技巧与点评标准回答线程池感知任务完成有几种方式一是通过 Future.get() 阻塞等待单个任务完成并获取结果二是用 CompletionService 批量提交任务按完成顺序获取结果先完成先拿到三是用 CountDownLatch 等待所有任务完成不关心结果四是用 CompletableFuture 实现非阻塞的回调式通知。其中 CompletionService 解决了 Future.get() 串行等待的问题CompletableFuture 是最现代的异步编程方式。加分回答CompletionService 的原理它内部维护了一个 BlockingQueueFuture把 Executor 和 BlockingQueue 组合在一起。任务完成后ExecutorCompletionService 会把 Future 封装成 QueueingFuture覆盖了 done() 方法任务完成时自动入队。这是生产者-消费者模式的精巧应用Future.get() 的超时陷阱get(timeout) 超时后只是抛 TimeoutException任务仍在后台执行。如果需要真正取消任务应该 catch 超时后调用 future.cancel(true)CompletableFuture 的优势它不仅支持 thenAccept 回调还支持 thenCombine合并两个结果、thenCompose链式异步、allOf等全部、anyOf任一完成等丰富的组合操作是 Java 异步编程的首选面试官点评这道题考的是你对并发工具链的全面掌握。能说出 Future 和 CountDownLatch 是基本要求能讲清 CompletionService 按完成顺序获取的原理、以及 CompletableFuture 的回调优势才说明你有过批量任务处理的实战经验。面试官最想听到的是你不仅知道有哪些方式还能根据场景做出正确的选择。原文阅读内容有帮助点赞、收藏、关注三连评论区等你

相关文章:

孤舟笔记 并发篇二十四 线程池如何知道一个线程的任务已经执行完成?三种方式各有乾坤

文章目录一、先说结论:感知任务完成的三种方式二、方式一:Future.get()三、方式二:CompletionService四、方式三:CountDownLatch五、方式四:FutureTask 回调六、对比总结感知任务完成方式全景回答技巧与点评标准回答加…...

Proteus 8.15 安装后汉化失败?手把手教你搞定中文界面和破解激活

Proteus 8.15 汉化与激活疑难排查指南 作为一名长期使用Proteus进行电路仿真的工程师,我深知这个工具在电子设计领域的重要性。但很多新手在安装后往往会遇到汉化失败或激活无效的问题,导致软件无法正常使用。本文将针对这些常见痛点,提供一套…...

告别蓝牙RSSI定位不准!手把手教你用Nordic nRF52840搭建厘米级AOA定位系统

厘米级蓝牙AOA定位实战:基于nRF52840的仓库资产追踪方案 在工业仓储环境中,传统蓝牙RSSI定位技术常因多径效应和信号波动导致定位误差高达3-5米,使得贵重资产追踪变成一场"捉迷藏"游戏。而采用蓝牙5.1的AOA(到达角&…...

新手也能懂的USB3.0 PCB设计:用两层板搞定VL817芯片的90Ω差分线(附阻抗计算与铺铜避坑)

新手也能懂的USB3.0 PCB设计:用两层板搞定VL817芯片的90Ω差分线 作为一名硬件设计新手,第一次接触USB3.0高速信号布线时,面对90Ω阻抗控制、差分对走线、GND via阵列这些专业术语,难免会感到一头雾水。本文将从一个真实的双层板设…...

C语言RTOS多核协同失效真相:Cache一致性缺失、内存序乱序、GCC -O2优化陷阱——三重危机诊断工具链实战

更多请点击: https://intelliparadigm.com 第一章:C语言RTOS多核协同失效的系统性认知 在嵌入式实时系统中,基于C语言开发的RTOS(如FreeRTOS、Zephyr或RT-Thread)常被移植至ARM Cortex-A/R系列或多核RISC-V SoC平台。…...

全面掌握AssetRipper:从Unity资源提取到多平台部署的完整指南

全面掌握AssetRipper:从Unity资源提取到多平台部署的完整指南 【免费下载链接】AssetRipper GUI Application to work with engine assets, asset bundles, and serialized files 项目地址: https://gitcode.com/GitHub_Trending/as/AssetRipper AssetRipper…...

Zotero重复文献终极处理方案:ZoteroDuplicatesMerger完整使用指南

Zotero重复文献终极处理方案:ZoteroDuplicatesMerger完整使用指南 【免费下载链接】ZoteroDuplicatesMerger A zotero plugin to automatically merge duplicate items 项目地址: https://gitcode.com/gh_mirrors/zo/ZoteroDuplicatesMerger 如果你正在为Zot…...

在 Node.js 服务中异步调用 Taotoken 提供的多模型聊天补全接口

在 Node.js 服务中异步调用 Taotoken 提供的多模型聊天补全接口 1. 准备工作 在开始编写 Node.js 服务代码前,需要完成以下准备工作。首先确保已注册 Taotoken 账号并获取有效的 API Key。登录 Taotoken 控制台后,可以在「API 密钥管理」页面创建新的密…...

Zotero GPT终极指南:用AI轻松读懂学术文献的研究态度与情感倾向

Zotero GPT终极指南:用AI轻松读懂学术文献的研究态度与情感倾向 【免费下载链接】zotero-gpt GPT Meet Zotero. 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-gpt 你是否曾被海量学术文献淹没?是否在阅读论文时难以快速把握作者的研究立场…...

Ubuntu 20.04/22.04 安装 ITK-SNAP 医学图像工具,手把手解决 libpng12 依赖报错

Ubuntu 20.04/22.04 安装 ITK-SNAP 医学图像工具全攻略:从依赖报错到完美运行 在医学影像分析和生物信息学研究领域,ITK-SNAP 作为一款开源的图像分割工具,凭借其强大的三维可视化功能和半自动分割算法,已成为众多研究人员的首选…...

Altium Designer 23 分层打印PCB/SCH的保姆级避坑指南(附正确层顺序)

Altium Designer 23 分层打印PCB/SCH的保姆级避坑指南(附正确层顺序) 在电子设计领域,Altium Designer(简称AD)无疑是工程师们的得力助手。然而,对于刚接触AD23的新手来说,分层打印功能常常成为…...

别再死记硬背DDR4时序参数了!用Python脚本自动解析JESD79-4标准文档,生成你的专属配置表

用Python解放DDR4开发:从JESD79-4标准文档自动生成配置工具 当第一次打开JESD79-4标准文档时,大多数硬件工程师都会感到一阵眩晕——数百页的技术规范、错综复杂的时序参数、晦涩难懂的寄存器配置,这些内容不仅难以记忆,更在具体项…...

互联网大厂Java面试实战:从Spring Cloud微服务到Redis缓存的电商高并发场景

互联网大厂Java面试实战:从Spring Cloud微服务到Redis缓存的电商高并发场景 前言 本文记录了一次真实的互联网大厂Java高级开发岗位面试过程,通过严肃面试官与搞笑程序员"谢飞机"的对话形式,展现面试中的经典技术问题与业务场景思考…...

如何快速下载小红书无水印作品:XHS-Downloader完全指南

如何快速下载小红书无水印作品:XHS-Downloader完全指南 【免费下载链接】XHS-Downloader 小红书(XiaoHongShu、RedNote)链接提取/作品采集工具:提取账号发布、收藏、点赞、专辑作品链接;提取搜索结果作品、用户链接&am…...

windows10-11 设置20年不自动更新方法

一 win10方法:修改注册表暂停 10 年按 WinR 输入 regedit 并回车,打开注册表编辑器。定位到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings。在右侧空白处右键选择 新建 > DWORD(32位)值。将名称设为 FlightSettingsMaxPauseDays…...

荒野大镖客2修改器2026最新版下载(附安装教程)

一、修改器核心亮点 适配性强:完美兼容游戏最新v1491.50版本,支持Steam/EPIC双平台 稳定性高:实测连续使用一周无闪退、卡顿,运行流畅 中文友好:内置中文界面,无需额外汉化补丁 功能全面:覆盖…...

保姆级教程:用Playwright + pytest + Allure 给你的Web自动化测试做个“体检报告”

从零打造企业级Web自动化测试报告:Playwright pytest Allure深度实践指南 当你的自动化测试脚本运行时,是否遇到过这样的困境:测试失败时开发人员无法快速定位问题,管理层对测试结果的可视化程度不满意,团队协作效率…...

《扣子开发AI Agent智能体应用》全书案例重现

《扣子开发AI Agent智能体应用(人工智能技术丛书)》(宋立桓,王东健,陈铭毅,程东升)【摘要 书评 试读】- 京东图书 《扣子开发智能体应用》配套的课件和视频下载-CSDN博客 【图书介绍】《扣子开发AI Agent智能体应用》…...

图吧工具箱专业版下载2026最新版:硬件检测与测试工具集附带安装教程

图吧工具箱由国内硬件爱好者团队“图拉丁吧”开发并维护,集硬件检测、性能测试、故障诊断、系统优化于一体,免费。该工具集整合了数十款硬件检测与测试工具,统一界面,分类清晰。专业版在原版基础上移除了冗余组件,增加…...

揭秘国产存算一体芯片C语言编程陷阱:3类常见指令调用错误及硬件级调试方案

更多请点击: https://intelliparadigm.com 第一章:国产存算一体芯片C语言编程陷阱总览 国产存算一体(Computing-in-Memory, CIM)芯片在架构上打破了冯诺依曼瓶颈,将计算单元深度嵌入存储阵列。这种硬件范式变革直接导…...

压电主动消声器研究【附COMSOL仿真】

✅ 博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。 ✅ 如需沟通交流,扫描文章底部二维码。 (1)压电材料吸声理论建模与传感器信号提取: 以压电…...

Web-Check网站链接分析终极指南:一键掌握内部与外链结构的完整方案

Web-Check网站链接分析终极指南:一键掌握内部与外链结构的完整方案 【免费下载链接】web-check 🕵️‍♂️ All-in-one OSINT tool for analysing any website 项目地址: https://gitcode.com/GitHub_Trending/we/web-check Web-Check是一款功能强…...

拓扑优化减应力方法【附ABAQUS仿真】

✅ 博主简介:擅长数据搜集与处理、建模仿真、程序设计、仿真代码、论文写作与指导,毕业论文、期刊论文经验交流。 ✅ 如需沟通交流,扫描文章底部二维码。(1)消除中间密度单元的二值化处理方法:在传统SIMP变…...

Vision Transformer错误处理终极指南:异常检测与恢复机制详解

Vision Transformer错误处理终极指南:异常检测与恢复机制详解 【免费下载链接】vit-pytorch Implementation of Vision Transformer, a simple way to achieve SOTA in vision classification with only a single transformer encoder, in Pytorch 项目地址: http…...

ProxiTok隐私保护深度解析:为什么你应该从TikTok切换到ProxiTok

ProxiTok隐私保护深度解析:为什么你应该从TikTok切换到ProxiTok 【免费下载链接】ProxiTok Open source alternative frontend for TikTok made using PHP 项目地址: https://gitcode.com/gh_mirrors/pr/ProxiTok ProxiTok是一款开源的TikTok替代前端&#x…...

Zig 项目反AI贡献政策:一场关于开源灵魂的保卫战

Zig 项目反AI贡献政策:一场关于开源灵魂的保卫战 2026年4月,Zig编程语言项目发布了一项引发广泛争议的政策:禁止使用AI工具(如GitHub Copilot、ChatGPT等)生成的代码贡献。这一决定在Hacker News上获得了566票的热烈讨…...

Diagon命令行工具完整使用手册:从安装到精通

Diagon命令行工具完整使用手册:从安装到精通 【免费下载链接】Diagon Interactive ASCII art diagram generators. :star2: 项目地址: https://gitcode.com/gh_mirrors/di/Diagon Diagon是一款强大的交互式ASCII艺术图表生成工具,能够将markdown风…...

你的汽车正在“告密”:如何彻底关闭车辆数据收集的完整技术指南

你的汽车正在“告密”:如何彻底关闭车辆数据收集的完整技术指南 引言 2025年3月,Rivian 官方支持页面上一则看似简单的 FAQ 引发了 Hacker News 社区的热烈讨论——“Can I disable all data collection from my vehicle?”(我能禁用车辆的所…...

ProxiTok主题定制完全教程:打造专属TikTok浏览体验

ProxiTok主题定制完全教程:打造专属TikTok浏览体验 【免费下载链接】ProxiTok Open source alternative frontend for TikTok made using PHP 项目地址: https://gitcode.com/gh_mirrors/pr/ProxiTok ProxiTok作为一款开源的TikTok替代前端,不仅让…...

【生产级Python风控代码库】:基于Celery+Redis Stream+Drools轻量替代方案,已支撑日均800万笔交易

更多请点击: https://intelliparadigm.com 第一章:生产级Python电商实时风控系统架构全景 现代电商风控系统需在毫秒级完成欺诈识别、异常行为拦截与动态策略决策,其架构必须兼顾低延迟、高吞吐、强一致性与策略可热更能力。典型生产级架构采…...