天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。
今天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。
1.线程池核心的参数
1.线程核心数- 线程池中始终保持的活动线程数量。
2.最大线程数- 线程池能够容纳的最大线程数量。
3.等待队列- 用于存储等待执行的任务的队列。
4.线程存活时间- 没有任务额外的线程会保持活动状态的时间。
5.时间单位-可以是毫秒,秒。
6.线程工厂- 创建一个线程工厂。
7.拒绝策略- 线程池的任务队列已满,新任务的处理方式。
举个列子:
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(),new ThreadFactoryBuilder().setThreadFactory(new DefaultThreadFactory("task-inspection")).setUncaughtExceptionHandler((t, e) -> log.error("{}", t, e)).build());
2.线程池的运行原理
想象你是一家快餐店的老板,你的店里经常有顾客需要服务。你有一些员工,每个员工可以为顾客制作食物。但是,你不可能每次有顾客来的时候都去雇佣新员工,因为雇佣和解雇都需要花费时间和金钱。
于是,你决定采用一种聪明的方式来管理员工:你雇佣了一组员工,让他们一直待在店里,准备着做食物的工作。当有顾客来了,你只需要把订单交给员工,他们就会按照订单制作食物。这样,你节省了雇佣和解雇的麻烦,员工也可以充分利用自己的时间,不必一直等着顾客。
线程池就像是这家快餐店的员工组合。线程池会事先创建一些线程,就像员工待在店里准备做工作。当有任务需要执行时,就把任务交给线程池,就像把订单交给员工。线程池的线程会按顺序执行任务,然后再继续执行下一个任务,就像员工按照订单制作食物。
线程池的运行原理可以分为以下几个步骤:
- 线程池的创建:在程序初始化或需要使用线程池时,创建一个线程池对象。这个线程池对象会根据配置参数来初始化一定数量的线程,以及一个任务队列用于存放待执行的任务。
- 任务提交:当有任务需要执行时,应用程序通过将任务对象提交给线程池。这些任务会被放入任务队列中,等待线程池中的空闲线程来执行。
- 线程池的管理:线程池会根据配置的核心线程数和最大线程数来管理线程的数量。如果任务数量小于核心线程数,线程池会创建新线程来执行任务。如果任务数量大于核心线程数,但小于最大线程数,线程池会将任务放入任务队列中等待执行,而不会创建新线程。如果任务数量超过最大线程数,线程池会根据拒绝策略来处理任务,例如丢弃任务或抛出异常。
- 任务执行:线程池中的线程会从任务队列中取出任务并执行。线程池会不断地从任务队列中取任务,确保所有任务都得到执行。执行完任务后,线程会继续从队列中取下一个任务。
- 线程回收:在任务执行完毕后,线程池会根据一定的策略来决定是否回收线程。如果线程池的活动线程数量超过核心线程数,空闲的线程会在一定时间内保持活动状态,以备下次任务使用。如果空闲时间超过一定阈值,额外的线程可能会被终止以节省资源。
3.如何解决这样的问题,我考虑使用 CountDownLatch
1、为什么我会使用 CountDownLatch ?
在上一家公司实际开发过程当中,就遇到过并行的问题。那个时候是要多个任务都执行,但是并没有去保证他的一个执行的顺序。于是我们就使用到了CountDownLatch 使用计数器去判断这些所有的业务逻辑是否都执行完毕,从而进行下一步操作。
部分的代码代码如下:
private static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(10, 10,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>(),new ThreadFactoryBuilder().setThreadFactory(new DefaultThreadFactory("task-inspection")).setUncaughtExceptionHandler((t, e) -> log.error("{}", t, e)).build()); @Override@Transactional(rollbackFor = Exception.class)public void asyncInitiatingInspection(InspectionRecordsBO bo) {CountDownLatch countDownLatch = new CountDownLatch(inspectionBaseServiceList.size());inspectionBaseServiceList.forEach(inspectionBaseService -> {threadPoolExecutor.execute(() -> {try {MDCUtil.putMDCKey(IdGenUtils.generateRequestId());inspectionBaseService.addInspection(bo);} catch (Exception e) {log.error("发起巡检信息失败类:{},发起巡检信息失败:{}", inspectionBaseService.getClass().getName(), e);} finally {countDownLatch.countDown();MDCUtil.removeMDCKey();}});});try {// 等待所有线程执行完毕countDownLatch.await();} catch (InterruptedException e) {log.error("线程计数器失败:" + e);Thread.currentThread().interrupt();}// 判断是否所有巡检已完this.updateInspectionResult(bo);}
2、什么是 CountDownLatch ?
CountDownLatch 是 Java 标准库中的一个同步工具,用于在多个线程之间进行协调和控制。它可以帮助一个或多个线程等待其他线程完成一组操作,然后再继续执行。
你可以将 CountDownLatch 想象成一个倒计时计数器,可以设置一个初始计数值,然后多个线程可以等待这个计数器减为零,之后再继续执行。
主要的操作方法有两个:
await()方法:调用这个方法的线程会被阻塞,直到计数器减到零。其他线程完成一定操作后,调用countDown()方法来减小计数器的值。当计数器变为零时,被阻塞的线程会继续执行。countDown()方法:这个方法用于减小计数器的值。当一个线程完成了一个操作,可以调用这个方法来减小计数器的值。
CountDownLatch 在多线程编程中常常用于实现“等待所有线程完成某个任务后再继续”的场景。例如,在主线程中等待多个子线程都完成某些操作后再进行下一步操作。
3.解决方案
package com.aq.test;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;public class TestCountDownLatch {public static void main(String[] args) {CountDownLatch latch1 = new CountDownLatch(0);CountDownLatch latch2 = new CountDownLatch(1);CountDownLatch latch3 = new CountDownLatch(1);ExecutorService executor = Executors.newFixedThreadPool(3);executor.submit(() -> {try {latch1.await();System.out.println("线程A执行完毕");// todo 业务逻辑} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {latch2.countDown();}});executor.submit(() -> {try {latch2.await();System.out.println("线程B执行完毕");// todo 业务逻辑} catch (InterruptedException e) {Thread.currentThread().interrupt();} finally {latch3.countDown();}});executor.submit(() -> {try {latch3.await();System.out.println("线程C执行完毕");// todo 业务逻辑} catch (InterruptedException e) {Thread.currentThread().interrupt();}});latch1.countDown();executor.shutdown();}
}
我们使用了三个 CountDownLatch,分别用于控制三个线程的执行顺序。每个线程在执行之前都会通过 await 方法等待前一个线程的 CountDownLatch 计数减为0,然后执行自己的任务。
通过适时的 countDown 调用,我们确保了线程的顺序执行。在这个例子中,线程A会先执行,然后是线程B,最后是线程C。
总结,通过自己的理解和在网上寻找答案。以上就是我对于这几个问题的解决方案和解决思路。
相关文章:
天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。
今天去面试的时候,遇到一个问题。我三个任务,ABC,我怎么让A执行完执行B,B执行完执行C 3个并行线程,如何解决。程池的核心运行原理和参数。 1.线程池核心的参数 1.线程核心数- 线程池中始终保持的活动线程数量。 2.最…...
使用finksql方式将mysql数据同步到kafka中,每次只能同步一张表
使用finksql方式将mysql数据同步到kafka中,每次只能同步一张表 package flink;import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.table.api.TableResult; import org.apache.flink.table.api.bridge.java.…...
ios开发 swift5 苹果系统自带的图标 SF Symbols
文章目录 1.官网app的下载和使用2.使用代码 1.官网app的下载和使用 苹果官网网址:SF Symbols 通过上面的网址可以下载dmg, 安装到自己的mac上 貌似下面这样不能展示出动画,还是要使用动画的代码 .bounce.up.byLayer2.使用代码 UIKit UIImage(system…...
Linux内核源码分析 (3)调度器的实现
Linux内核源码分析 (3)调度器的实现 文章目录 Linux内核源码分析 (3)调度器的实现一、概述二、调度器数据结构1、task_struct中与调度有关的的成员2、调度器类3、就绪队列4、调度实体 三、处理优先级1、优先级的内核表示2、计算优先级3、计算负荷权重 四、核心调度器1、周期性调…...
网络安全法+网络安全等级保护
网络安全法 网络安全法21条 网络安全法31条 网络安全等级保护 网络安全等级保护分为几级? 一个中心,三重防护 等级保护2.0网络拓扑图 安全区域边界 安全计算环境 等保安全产品 物理机房安全设计...
持续集成对软件项目管理的作用
l、对项目目标管理的作用 软件项目的目标是开发出可运行的、客户满意的软件系统持续集成有统一的代 码库。要求开发人员定期地、不断地向代码库提交代码。新近提交的代码会经过编 译与测试.与代码库中旧有的代码相整合,形成安全稳定运行的代码库&…...
【Qt QAxObject】使用 QAxObject 高效任意读写 Excel 表
1. 用什么操作 Excel 表 Qt 的官网库中是不包含 Microsoft Excel 的操作库,关于对 Microsoft Excel 的操作库可选的有很多,包含基于 Windows 系统本身的 ActiveX、Qt Xlsx、xlsLib、LibXL、qtXLS、BasicExcel、Number Duck。 库.xls.xlsx读写平台Qt Xls…...
java八股文面试[多线程]——自旋锁
优点: 1. 自旋锁尽可能的减少线程的阻塞,这对于锁的竞争不激烈,且占用锁时间非常短的代码块来说性能能大幅度的提升,因为自旋的消耗会小于线程阻塞挂起再唤醒的操作的消耗 ,这些操作会导致线程发生两次上下文切换&…...
分布式系统的多数据库,实现分布式事务回滚(1.7.0 seata整合2.0.4nacos)
正文 1、解决的应用场景是分布式事务,每个服务有独立的数据库。 2、例如:A服务的数据库是A1,B服务的数据库是B2,A服务通过feign接口调用B服务,B涉及提交数据到B2,业务是在B提交数据之后,在A服…...
PDF可以修改内容吗?有什么注意的事项?
PDF是一种跨平台的电子文档格式,可以在各种设备上轻松阅读和共享。许多人喜欢将文档转换为PDF格式以确保格式的一致性和易读性。但是,PDF文件一般被认为是“只读”文件,即无法编辑。那么,PDF文件是否可以修改呢? 答案是…...
自动泊车的自动驾驶控制算法
1. 自动泊车系统 自动泊车系统(AutomatedParkingASSiSt,APA)利用车辆搭载的传感器感知车辆周边环境,扫描满足当前车辆停放的障碍物空间车位或线车位,并通过人机交互(HumanMachine Interface,HMI)获取驾驶员对目标车位的选择或自动确定目标车位,自动规划泊车路径,通过控制器向车…...
Java doc等文件生成PDF、多个PDF合并
之前写过一遍文章是 图片生成PDF。 今天继续来对 doc等文件进行pdf合并以及多个pdf合并为一个pdf。 兄弟们,还是开箱即用。 1、doc生成pdf 依赖 <!-- doc生成pdf --><dependency><groupId>com.aspose</groupId><artifactId>aspose…...
【C++】list类的模拟实现
🏖️作者:malloc不出对象 ⛺专栏:C的学习之路 👦个人简介:一名双非本科院校大二在读的科班编程菜鸟,努力编程只为赶上各位大佬的步伐🙈🙈 目录 前言一、list类的模拟实现1.1 list的…...
机械臂+2d相机实现复合机器人定位抓取
硬件参数 机械臂:艾利特 相机:海康相机 2d识别库:lindmod,github可以搜到 光源:磐鑫光源 软件参数 系统:windows / Linux 开发平台:Qt 开发语言:C 开发视觉库:OpenCV …...
网络编程 http 相关基础概念
文章目录 表单是什么http请求是什么http请求的结构和说明关于http方法 GET和POST区别http常见状态码http响应http 请求是无状态的含义html是什么 (前端内容,了解即可)html 常见标签 (前端内容,了解即可)关于…...
LatexEasy公式渲染教程
LatexEasy使用简单的URL渲染公式为图片 https://r.latexeasy.com/image.svg?1-sin^2(x) 使用单个HTML图像标签将公式添加到任何现有网站 <img src"https://r.latexeasy.com/image.svg?1-sin^2(x)" />...
十年测试工程师叙述自动化测试学习思路
自动化测试介绍 自动化测试(Automated Testing),是指把以人为驱动的测试行为转化为机器执行的过程。实际上自动化测试往往通过一些测试工具或框架,编写自动化测试用例,来模拟手工测试过程。比如说,在项目迭代过程中,持…...
SpringAOP详解(下)
proxyFactory代理对象创建方式和代理对象调用方法过程: springaop创建动态代理对象和代理对象调用方法过程: 一、TargetSource的使用 Lazy注解,当加在属性上时,会产生一个代理对象赋值给这个属性,产生代理对象的代码为…...
主流软件漏洞跟踪 Apache RocketMQ NameServer 远程代码执行漏洞(CVE-2023-37582)
主流软件漏洞跟踪 Apache RocketMQ NameServer 远程代码执行漏洞(CVE-2023-37582) 漏洞描述影响版本安全版本如何修复可供参考的资料主流软件漏洞跟踪 Apache RocketMQ NameServer 远程代码执行漏洞(CVE-2023-37582) CVE编号 : CVE-2023-37582 利用情况 : EXP 已公开 …...
Element table根据字段合并表格(可多字段合并),附带拖拽列动态合并
效果如图,姓名 数值1 字段进行自动合并 封装合并列js - tableMerge.js // 获取列合并的行数 // params // tableData: 表格数据 // mergeId: 合并的列的字段名 export const tagRowSpan (tableData, mergeId) >{const tagArr [];let pos 0;tableData.map((i…...
Nanobot技能扩展开发:自定义OpenClaw功能模块教程
Nanobot技能扩展开发:自定义OpenClaw功能模块教程 1. 引言 想给你的Nanobot智能助手添加一些个性化功能吗?比如让它帮你查天气、管理待办事项,或者连接你常用的办公软件?今天就来手把手教你如何为Nanobot开发自定义技能模块。 …...
Java函数计算部署被低估的致命风险:类加载冲突、内存泄漏、上下文丢失——3个真实P0故障复盘
第一章:Java函数计算部署被低估的致命风险:类加载冲突、内存泄漏、上下文丢失——3个真实P0故障复盘在Serverless架构下,Java函数计算因其启动慢、内存占用高而常被“降级使用”,但更隐蔽的风险来自运行时环境的不可见性。我们复盘…...
程序员必看!用UML类图破解Spring Boot领域模型设计难题
程序员必看!用UML类图破解Spring Boot领域模型设计难题 在Spring Boot项目中,领域模型设计往往是决定系统可维护性和扩展性的关键。许多Java开发者虽然熟练使用JPA和MyBatis,但当面对复杂的业务逻辑时,却常常陷入"贫血模型&q…...
T/SCSIA0018-2025《四川省信息技术应用创新项目费用测算标准》标准解读
此前四川省存量信息系统信创适配改造项目长期面临费用测算无统一标准、议价争议多、成本虚高、重复计费等行业痛点,给项目估算、审计、结算带来诸多困扰。2025年12月29日发布的T/SCSIA0018-2025《四川省信息技术应用创新项目费用测算标准》,作为省内首个…...
nRF54L15实现更快的处理速度
Nordic的nRF54L15系统级芯片相比前代nRF52系列,不仅速度更快、功耗更低,还配备了更丰富的外设,” 刘佳杭继续说道,“基于Arm Cortex-M33处理器的HJ-N54L_SIP不仅能处理更复杂的应用程序,同时显著提升了处理速度。系统级…...
STM32+FreeRTOS双分区开发避坑指南:Bootloader跳转前别忘了这行关键代码
STM32FreeRTOS双分区开发避坑指南:Bootloader跳转前别忘了这行关键代码 当你在STM32上实现BootloaderApp双分区架构时,是否遇到过这样的场景:Bootloader明明成功跳转到了应用程序,却在启动FreeRTOS调度器时突然崩溃?寄…...
Logisim实战:8位可控加减法电路设计与溢出检测
1. 从零开始理解8位可控加减法电路 第一次接触数字电路设计的朋友可能会觉得"8位可控加减法电路"听起来很高深,其实它的核心原理就像我们小时候用的算盘。想象一下,你有一个8档的算盘,每档只能表示0或1(对应算珠的上或下…...
深度解析ThreeFingerDragOnWindows:Windows触控板三指拖动技术实现
深度解析ThreeFingerDragOnWindows:Windows触控板三指拖动技术实现 【免费下载链接】ThreeFingersDragOnWindows Enables macOS-style three-finger dragging functionality on Windows Precision touchpads. 项目地址: https://gitcode.com/gh_mirrors/th/ThreeF…...
AutoGLM-Phone-9B快速上手:图文语音全能AI,小白也能轻松部署
AutoGLM-Phone-9B快速上手:图文语音全能AI,小白也能轻松部署 1. AutoGLM-Phone-9B简介 1.1 什么是AutoGLM-Phone-9B AutoGLM-Phone-9B是一款专为移动设备优化的多模态AI模型,它能同时理解文字、图片和语音信息。简单来说,就像给…...
SD-WebUI Cleaner 终极指南:AI图像清理与对象移除完整教程
SD-WebUI Cleaner 终极指南:AI图像清理与对象移除完整教程 【免费下载链接】sd-webui-cleaner An extension for stable-diffusion-webui to remove any object. 项目地址: https://gitcode.com/gh_mirrors/sd/sd-webui-cleaner 你是否曾经想要从照片中移除不…...
