线程池-1:线程池是如何复用线程的?

这段代码实现了一个简单的线程池 SimpleThreadPool。主要包括以下几个关键部分:

  1. 构造函数:初始化最大线程数 maxPoolSize、任务队列 taskQueue、当前线程数 currentPoolSize,以及锁 lock 和条件 taskAvailable

  2. submit(Runnable task) 方法:用于提交任务到线程池。如果当前线程数小于最大线程数,会创建并启动一个新的工作线程来执行任务;否则将任务加入任务队列,并通过条件变量通知等待的线程来处理任务。

  3. 内部类 Worker:实现了工作线程的逻辑。在运行时,工作线程会循环从任务队列中取出任务并执行,如果队列为空则会等待条件变量通知。该内部类实现了 Runnable 接口,用于执行具体的任务。

  4. main 方法:在主方法中创建了一个 SimpleThreadPool 实例,并提交了10个任务给线程池。

需要注意的是,该线程池实现是一个简单的固定大小线程池,当任务数量超过最大线程数时,多余的任务会被放入任务队列中等待执行。代码中并没有为每个任务都创建一个新的线程,在 submit(Runnable task) 方法中,只有当当前线程数小于最大线程数时才会创建新的工作线程来执行任务。如果当前线程数已经达到最大线程数,则会将任务加入任务队列中,等待空闲线程来执行。因此,这个线程池实际上是一个固定大小的线程池,它会复用线程而不是为每个任务都创建一个新的线程。这样可以更有效地利用线程资源,并避免频繁地创建和销毁线程带来的开销。

在实际应用中,可以根据需求进一步扩展和优化线程池的功能,比如增加线程池的关闭方法、异常处理机制等,以确保线程池的稳定性和可靠性。


public class SimpleThreadPool {// 最大线程数private final int maxPoolSize;// 任务队列private final Queue<Runnable> taskQueue;// 当前线程数private int currentPoolSize;private final Lock lock = new ReentrantLock();private final Condition taskAvailable = lock.newCondition();public SimpleThreadPool(int maxPoolSize) {this.maxPoolSize = maxPoolSize;this.taskQueue = new LinkedList<>();this.currentPoolSize = 0;}public void submit(Runnable task) {lock.lock();try {// 将任务入队列if (currentPoolSize < maxPoolSize) {// 构建工作线程Worker worker = new Worker(task);// 启动线程worker.thread.start();currentPoolSize++;} else {taskQueue.offer(task);// 释放信号通知处理任务taskAvailable.signal();}} finally {lock.unlock();}}private class Worker implements Runnable {final Thread thread;Runnable firstTask;Worker(Runnable firstTask) {this.firstTask = firstTask;this.thread = new Thread(this);}public void run() {Runnable task = this.firstTask;this.firstTask = null;while (true) {lock.lock();try {if (task != null || (task = taskQueue.poll()) != null) {try {task.run();} catch (RuntimeException e) {e.printStackTrace();} finally {task = null;}} else {try {taskAvailable.await();} catch (InterruptedException e) {e.printStackTrace();}}} finally {lock.unlock();}}}}public static void main(String[] args) {SimpleThreadPool threadPool = new SimpleThreadPool(5);// 提交10个任务给线程池for (int i = 0; i < 10; i++) {final int task = i;threadPool.submit(() -> {String threadName = Thread.currentThread().getName();System.out.println("Task " + task + " is running on " + threadName);});}}
}

运行结果如图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/776158.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PSINS初学指导

2024-3-27/Evand/Ver1 因为惯导解算设计的数学公式很多&#xff0c;在编程时如果一步一步自己编&#xff0c;非常耗时耗力&#xff0c;所以在进行上层设计时&#xff0c;借助工具箱完成底层的复杂计算是很有必要的。另一方面&#xff0c;也能利用工具箱进行惯导解算方面的学习…

FPGA时钟资源详解(2)——Clock-Capable Inputs

FPGA时钟系列文章总览&#xff1a;FPGA原理与结构&#xff08;14&#xff09;——时钟资源https://ztzhang.blog.csdn.net/article/details/132307564 目录 一、概述 1.1 为什么使用CC 1.2 如何使用CC 二、Clock-Capable Inputs 2.1 SRCC 2.2 MRCC 2.3 其他用途 2.3.1…

WIFI驱动移植实验:WIFI驱动加载测试

一. 简介 前面文章学习了向kernel内核源码中添加 trl8188驱动代码&#xff0c;配置内核以支持 WIFI设备&#xff0c;使能WIFI功能。文章地址如下&#xff1a; WIFI驱动移植实验&#xff1a;删除Linux内核自带的 RTL8192CU 驱动-CSDN博客 WIFI驱动移植实验&#xff1a;将 rtl…

LeetCode 135. 分发糖果

n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&#xff0c;给这些孩子分发糖果&#xff1a; 每个孩子至少分配到 1 个糖果。相邻两个孩子评分更高的孩子会获得更多的糖果。 请你给每个孩子分发糖果&#xff0c;计算并返回需要准备的…

C语言中连字符“#”的使用,输出固件的编译时间和版本号

首先我们使用C语言宏定义和“#”来组合字符串 #define MAINVER 2#define SUBVER1 0#define SUBVER2 1#define STR(s) #s#define VERSION(a,b,c) "System V" STR(a) "." STR(b) "." STR(c) " "__DATE__ 然后我们在全局变量中定义一…

服务器硬件

目录 服务器CPU服务器GPU服务器内存服务器硬盘服务器主板散热系统&#xff08;服务器风扇&#xff09;服务器电源&#xff08;电影供应器&#xff09;其他网络适配器扩展卡 服务器CPU 基于架构的分类&#xff1a;根据CPU的架构不同&#xff0c;可以分为x86架构&#xff08;如I…

API接口鉴权签名设计

在设计API接口的鉴权签名时&#xff0c;通常会使用一种加密算法来生成签名&#xff0c;以确保请求的合法性和安全性。以下是通过鉴权签名的设计方案。 1、接口秘钥设置 Key:123 Secret:abc 2、接口Url 接口Url需要使用https的协议保证接口数据安全传输 3、请求参数 3.1、…

VsCode的json文件不允许注释的解决办法

右下角找到注释点进去 输入Files: Associations搜索出此项 改为项为*.json值为jsonc保存即可 然后会发现VsCode的json文件就允许注释了

哈工大 sse C语言 困难

Q1892.(10分数, 语言: C)Two Bags of Potatoes time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard output Valera had two bags of potatoes, the first of these bags contains x (x≥1) potatoes, and the second — y (y…

RAG进阶笔记:RAG进阶

1 查询/索引部分 1.1 层次索引 创建两个索引——一个由摘要组成&#xff0c;另一个由文档块组成分两步进行搜索&#xff1a;首先通过摘要过滤出相关文档&#xff0c;接着只在这个相关群体内进行搜索 1.2 假设性问题 让LLM为每个块生成一个假设性问题&#xff0c;并将这些问…

SQL104 返回产品名称和每一项产品的总订单数(left join..on.. ,group by)

select prod_name,count(order_num) as orders from Products P left join OrderItems OI on OI.prod_id P.prod_id group by prod_name order by prod_name;left join一个数据条多的表 count&#xff08;order_num&#xff09;,group by 另一个字段

C/C++ 各种编译器平台判断,返回对应平台CPU缩写符

参考以下实现&#xff0c;MIPS、ARM、RISV64、X86、X86_64、M68K、S390X、MIPS64、PPC64、LONGARCH32、LONGARCH64等。 const char* GetPlatformCode() noexcept { #if defined(__x86_64__) || defined(_M_X64)return "X86_64"; #elif defined(i386) || defined(__i3…

openEuler 22.03 安装 .NET 8.0

openEuler 22.03 安装 .NET 8.0 openEuler 22.03 安装 .NET 8.0 openEuler 22.03 安装 .NET 8.0 查看内核信息 [jeffPC-20240314EIAA ~]$ cat /proc/version Linux version 5.15.146.1-microsoft-standard-WSL2 (root65c757a075e2) (gcc (GCC) 11.2.0, GNU ld (GNU Binutils)…

ArkTS 的基本语法

ArkTS 的基本语法 ArkTS 是鸿蒙生态的应用开发语言。它在保持 TypeScript&#xff08;简称 TS&#xff09;基本语法风格的基础上&#xff0c;对 TS 的动态类型特性施加更严格的约束&#xff0c;引入静态类型。同时&#xff0c;提供了声明式 UI、状态管理等相应的能力&#xff…

全志R128 SDK HAL 模块开发指南——GPADC

GPADC 模块介绍 GPADC 是 12bit 采集精度的模数转换模块&#xff0c;支持 4 路通道&#xff0c;模拟输入范围 0-1.8v&#xff0c;最高采样率 1MHZ&#xff0c;并且支持数据比较&#xff0c;自校验功能&#xff0c;同时工作于可配置的四种工作模式&#xff1a; Single mode&a…

科学高效备考2024年汉字小达人:历年真题详细解析-古诗文专题10

距离2024年第11届汉字小达人比赛还有七个多月的时间&#xff0c;如何利用这段时间有条不紊地备考呢&#xff1f;我的建议是两手准备&#xff1a;①把小学1-5年级的语文课本上的知识点熟悉&#xff0c;重点是字、词、成语、古诗。阅读理解不需要。②把历年真题刷刷熟&#xff0c…

JAVA的sort用法详解(二维数组排序,List<>排序,lambada表达式,自定义类型排序)

目录 前言&#xff1a; 一维数组降序&#xff1a; 方法1.Comparator接口&#xff1a; 代码实现&#xff1a; 方法2.Collections.reverseOrder()&#xff1a; 代码实现&#xff1a; 二维数组排序&#xff1a; 代码如下&#xff1a; List<>排序&#xff1a; 代码…

Ansible-1

Ansible是一款自动化运维、批量管理服务器的工具&#xff0c;批量系统配置、程序部署、运行命令等功能。基于Python开发&#xff0c;基于ssh进行管理&#xff0c;不需要在被管理端安装任何软件。Ansible在管理远程主机的时候&#xff0c;只有是通过各种模块进行操作的。 需要关…

Linux 注入依赖环境

文章目录 配置依赖程序安装 JDK安装 Tomcat安装 mysql 配置依赖程序 下面配置依赖程序都以CentOS为例。 安装 JDK 可以直接使用 yum(CentOS) 直接进行安装。 先搜索&#xff0c;确定软件包的完整名称。 yum list | grep jdk再进行安装 进行安装的时候一定要先确保处在“管理…

【详细讲解React 快速入门教程】

&#x1f525;博主&#xff1a;程序员不想YY啊&#x1f525; &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家&#x1f4ab; &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 &#x1f308;希望本文对您有所裨益&#xff0c;如有…