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

线程池-抢票系统性能优化

文章目录

    • 引言-购票系统
    • 线程池
      • 购票系统-线程池优化
    • 池化 vs 未池化

引言-购票系统

public class App implements Runnable {private static int tickets = 100;private static int users = 10000;private final ReentrantLock lock = new ReentrantLock(true);public void run() {try {lock.lock();reduceTickets(); // 减票} finally {lock.unlock();}}private void reduceTickets() {if (tickets <= 0) return;System.out.println(Thread.currentThread().getName() + "抢到第" + tickets-- + "票");}private static void initTask(){App task = new App();Thread[] threads = new Thread[users];for (int i = 0; i < users; i++) {threads[i] = new Thread(task, "用户" + i);threads[i].start();}// 等待所有线程执行完毕for (Thread thread : threads) {try {thread.join();   // 让主线程等待该子线程执行完成后再继续} catch (InterruptedException e) {e.printStackTrace();}}}public static void main(String[] args) {long startTime = System.currentTimeMillis();// 初始化任务initTask();long endTime = System.currentTimeMillis();System.out.println("程序执行时间: " + (endTime - startTime) + " 毫秒");}
}

在前面,我们通过创建多个线程模拟抢票场景,并且使用加锁的方式解决了车票超卖的问题。

每次创建一个线程,都需要执行如下步骤:

  1. 手动创建一个线程对象
  2. 执行任务
  3. 执行完毕,释放线程对象

‼️当用户量较大时,就需要频繁的创建线程对象、释放线程对象,十分麻烦。

解决方案,则是引入线程池

  1. 线程复用:在线程池中初始化指定数量的核心线程数,用户需要时直接使用线程,不需要重新创建一个新的线程对象,实现对象的复用。
  2. 线程回收:执行完任务之后,线程不会销毁,而是放回线程池中继续等待使用。
  3. 提高系统的响应速度,线程的利用率。

线程池

Java线程池是一种用于优化线程使用和管理的工具,它通过复用一定数量的线程来执行多个任务,从而减少了创建和销毁线程的开销,提高了程序的性能和响应速度。

Java中的线程池是通过java.util.concurrent包下的Executor接口及其子类来实现的。

以下是一些关键的类和接口,用于在Java中创建和使用线程池:

  1. Executor接口:这是一个基础接口,用于执行提交的任务。
  2. ExecutorService接口:扩展了Executor接口,添加了用于管理执行器生命周期的方法,如关闭线程池。
  3. ThreadPoolExecutor类:是ExecutorService的一个实现,它允许更详细地配置线程池。
  4. Executors类:提供了创建线程池的工厂方法。

以下是几种常见的线程池类型,可以通过Executors类来创建:

  1. FixedThreadPool:固定数量的线程池,适用于负载比较重的服务器。
  2. SingleThreadExecutor:只有一个线程的线程池,适用于需要保证顺序执行的场景。
  3. CachedThreadPool:根据需要创建新线程的线程池,适用于执行很多短期异步任务的程序。
  4. ScheduledThreadPool:用于执行定时任务或周期性任务。

购票系统-线程池优化

  1. 初始化:线程池将根据预设配置初始化一定数量的核心线程。
  2. 新增线程:当任务提交量超过核心线程数时,系统会按需创建额外的工作线程以处理新增的任务负载。
  3. 最大线程数:若当前活跃的线程数目已达到设定的最大值,新到达的任务会被安排进入等待队列中暂存。
  4. 拒绝策略:在等待队列也达到了其容量上限的情况下,对于后续继续提交的新任务,线程池将依据预定义的拒绝策略进行处理,即不再接受新的任务请求。
public class ThreadPool implements Runnable {private static int tickets = 100;private static int users = 200000;private final ReentrantLock lock = new ReentrantLock(true);public void run() {try {lock.lock();reduceTickets(); // 减票} finally {lock.unlock();}}private void reduceTickets() {if (tickets <= 0) return;System.out.println(Thread.currentThread().getName() + "抢到第" + tickets-- + "票");}private static void initTask(){// 创建线程池ExecutorService pool = new ThreadPoolExecutor(5,    // 核心线程数16,   // 最大线程数0L, TimeUnit.MILLISECONDS,  // 线程空闲时间new LinkedBlockingQueue<Runnable>() // 任务队列);// 创建任务ThreadPool task = new ThreadPool();for (int i = 0; i < users; i++) {pool.submit(new Thread(task, "用户" + i));}// 执行完毕,关闭线程池pool.shutdown();try {// 等待所有线程执行完毕if (!pool.awaitTermination(10, TimeUnit.SECONDS)) {pool.shutdownNow(); // 超时强制关闭}} catch (InterruptedException e) {e.printStackTrace();}}public static void main(String[] args) {long startTime = System.currentTimeMillis();// 初始化任务initTask();long endTime = System.currentTimeMillis();System.out.println("程序执行时间: " + (endTime - startTime) + " 毫秒");}
}

池化 vs 未池化

  1. 电脑核心线程数( NumberOfCores ) = 12,逻辑核心数 = 16
  2. 票数 = 100,用户数量 = 10000,模拟 10000 个用户同事抢 100 张票。
****核心线程数最大线程数执行时间
未池化18832 ms
线程池配置 05854 ms
线程池配置 151056 ms
线程池配置 251627 ms

池化后,性能得到了质的飞跃🚀。

相关文章:

线程池-抢票系统性能优化

文章目录 引言-购票系统线程池购票系统-线程池优化 池化 vs 未池化 引言-购票系统 public class App implements Runnable {private static int tickets 100;private static int users 10000;private final ReentrantLock lock new ReentrantLock(true);public void run() …...

WebSocket 握手过程

文章目录 1. WebSocket 握手过程概述2. 客户端发送握手请求3. 服务器响应握手请求4. 客户端验证握手响应5. 建立 WebSocket 连接6. 安全性与注意事项7. 应用示例 在现代 Web 开发中&#xff0c;WebSocket 协议因其高效的实时通信能力而被广泛应用。WebSocket 允许客户端和服务器…...

VMware 虚拟机 ubuntu 20.04 扩容工作硬盘

一、关闭虚拟机 关闭虚拟机参考下图&#xff0c;在vmware 调整磁盘容量 二、借助工具fdisk testubuntu ~ $ df -h Filesystem Size Used Avail Use% Mounted on udev 1.9G 0 1.9G 0% /dev tmpfs 388M 3.1M 385M 1% /run /dev/sda5 …...

备战蓝桥杯:二分算法之牛可乐和魔法封印问题

这道题就是一道简单的模板题&#xff0c;我们分析一下&#xff01;&#xff0c;首先我们要找大于等于x的起始位置 我们还是用两个指针&#xff0c;left指向1&#xff0c;right指向n&#xff0c;如果a[mid]<x left mid1 如果a[mid]>x 就让right mid 如果数组全是小于x…...

普通用户授权docker使用权限

1、检查docker用户组 sudo cat /etc/group |grep docker 若显示&#xff1a;docker:x:999: # 表示存在否则创建docker用户组&#xff1a; sudo groupadd docker2、查看 /var/run/docker.sock 的属性 ll /var/run/docker.sock 显示&#xff1a; srw-rw---- 1 root root 0 1月…...

【实战篇】DeepSeek + ElevenLabs:让人工智能“开口说话”,打造你的专属语音助手!

最近,AI语音合成技术真是火得不行,各种“开口脆”的AI声音层出不穷,听得我直呼“这也太像真人了吧!” 作为一个科技爱好者,我当然不能错过这股潮流,这不,最近就沉迷于用 DeepSeek 和 ElevenLabs 这两款神器,捣鼓各种人声音频,简直停不下来! 先来科普一下这两位“主角…...

Vision Transformer:打破CNN垄断,全局注意力机制重塑计算机视觉范式

目录 引言 一、ViT模型的起源和历史 二、什么是ViT&#xff1f; 图像处理流程 图像切分 展平与线性映射 位置编码 Transformer编码器 分类头&#xff08;Classification Head&#xff09; 自注意力机制 注意力图 三、Coovally AI模型训练与应用平台 四、ViT与图像…...

LabVIEW国内外开发的区别

LabVIEW作为全球领先的图形化编程平台&#xff0c;在国内外工业测控领域均占据重要地位。本文从开发理念、技术生态、应用深度及自主可控性四个维度&#xff0c;对比分析国内外LabVIEW开发的差异&#xff0c;并结合国内实际应用场景&#xff0c;探讨其未来发展趋势。 ​ 一、开…...

【并发控制、更新、版本控制】.NET开源ORM框架 SqlSugar 系列

系列文章目录 &#x1f380;&#x1f380;&#x1f380; .NET开源 ORM 框架 SqlSugar 系列 &#x1f380;&#x1f380;&#x1f380; 文章目录 系列文章目录一、并发累计&#xff08;累加&#xff09;1.1 单条批量累计1.2 批量更新并且字段11.3 批量更新并且字段list中对应的…...

淘宝App交易链路终端混合场景体验探索

如何应对产品形态与产品节奏相对确定情况下转变为『在业务需求与产品形态高度不确定性的情况下&#xff0c;如何实现业务交付时间与交付质量的确定性』。我们希望通过混合架构&#xff08;Native 业务容器 Weex 2.0&#xff09;作为未来交易终端架构的重要演进方向&#xff0c…...

数据中心网络监控

数据中心是全球协作的特定设备网络&#xff0c;用来在internet网络基础设施上传递、加速、展示、计算、存储数据信息。 对于任何利用IT基础设施的企业来说&#xff0c;数据中心都是运营的核心&#xff0c;它本质上为整个业务网络托管业务应用程序和存储空间。数据中心可以是任…...

【含开题报告+文档+PPT+源码】基于springboot的汽车销售管理系统的设计与实现

开题报告 本论文聚焦于基于SpringBoot框架构建的汽车销售管理系统&#xff0c;该系统旨在赋能汽车销售企业实现一体化、智能化的业务运营与管理。管理员作为系统的核心员工群体&#xff0c;其功能权限深度集成并涵盖了登录认证、公告发布、人力资源调配、商品品牌管控、车辆信…...

flink cdc2.2.1同步postgresql表

目录 简要说明前置条件maven依赖样例代码 简要说明 在flink1.14.4 和 flink cdc2.2.1下&#xff0c;采用flink sql方式&#xff0c;postgresql同步表数据&#xff0c;本文采用的是上传jar包&#xff0c;利用flink REST api的方式进行sql执行。 前置条件 1.开启logical 确保你…...

rebase和merge

rebase 和merge区别&#xff1a; rebase变基&#xff0c;改变基底&#xff1a;rebase会抹去提交记录。 git pull 默认merge&#xff0c;git pull --rebase 变基 rebase C、D提交属于feature分支&#xff0c;是基于master分支&#xff0c;在B提交额外拉出来的&#xff0c;当…...

Spring boot中实现字典管理

数据库脚本 CREATE TABLE data_dict (id bigint NOT NULL COMMENT 主键,dict_code varchar(32) DEFAULT NULL COMMENT 字典编码,dict_name varchar(64) DEFAULT NULL COMMENT 字典名称,dict_description varchar(255) DEFAULT NULL COMMENT 字典描述,dict_status tinyint DEFA…...

调用DeepSeek官方的API接口

效果 前端样式体验链接&#xff1a;https://livequeen.top/deepseekshow 准备工作 1、注册deepseek官网账号 地址&#xff1a;DeepSeek 点击进入右上角【API开放平台】&#xff0c;并进行账号注册。 2、注册完成后&#xff0c;依次点击【API keys】-【生成API key】&#x…...

3.3 学习UVM中的uvm_driver 类分为几步?

文章目录 前言1. 定义2. 核心功能3. 适用场景4. 使用方法5. 完整代码示例5.1 事务类定义5.2 Driver 类定义5.3 Sequencer 类定义5.4 测试平台 6. 代码说明7. 总结 前言 以下是关于 UVM 中 uvm_driver 的详细解释、核心功能、适用场景、使用方法以及一个完整的代码示例&#xff…...

Python——批量图片转PDF(GUI版本)

目录 专栏导读1、背景介绍2、库的安装3、核心代码4、完整代码总结专栏导读 🌸 欢迎来到Python办公自动化专栏—Python处理办公问题,解放您的双手 🏳️‍🌈 博客主页:请点击——> 一晌小贪欢的博客主页求关注 👍 该系列文章专栏:请点击——>Python办公自动化专…...

科技查新过不了怎么办

“科技查新过不了怎么办&#xff1f;” “科技查新不通过的原因是什么&#xff1f;” 想必这些问题一直困扰着各位科研和学术的朋友们&#xff0c;尤其是对于查新经验不够多的小伙伴&#xff0c;在历经千难万险&#xff0c;从选择查新机构、填写线上委托单到付费&#xff0c;…...

WPS中如何批量上下居中对齐word表格中的所有文字

大家好&#xff0c;我是小鱼。 在日常制作Word表格时&#xff0c;经常需要对表格中的内容进行排版。经常会把文字设置成左对齐、居中对齐或者是右对齐&#xff0c;这些对齐方式都比较好设置&#xff0c;有时制作的表格需要把文字批量上下居中对齐&#xff0c;轻松几步就可以搞…...

【Docker】从瀑布开发到敏捷开发

引言 软件开发方法论是指导团队如何规划、执行和管理软件项目的框架。随着软件行业的不断发展&#xff0c;开发方法论也在不断演进。从传统的瀑布开发到现代的敏捷开发&#xff0c;软件开发方法论经历了深刻的变革。本文将详细探讨瀑布开发和敏捷开发的定义、特点、优缺点以及…...

若依框架二次开发——若依介绍、环境部署及更换项目包路径

文章目录 一、若依介绍1、项目简介2、主要特性3、技术选型4、内置功能5、文件结构6、配置文件7、核心技术介绍二、环境部署1、准备工作2、运行系统3、必要配置4、部署系统三、更换项目包路径1、更换目录名称2、更换顶级目录中的pom.xml3、更换项目所有包名称4、修改application…...

【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能&#xff08;AI&#xff09;通过算法模拟人类智能&#xff0c;利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络&#xff08;如ChatGPT&…...

996引擎-问题处理:三职业改单职业

996引擎-问题处理:三职业改单职业 问题解决方案顺便补充点单性别设置补充:可视化配置表参考资料问题 目前的版本: 引擎版本号:2024.8.7.0 三端配套客户端:3.40.9 传统PC客户端:23.12.07 配套数据库:64_24.8.7.0此版本需要通过可视化配置表...

Redis 发生宕机时,数据怎样恢复?

当 Redis 发生宕机时&#xff0c;数据恢复的核心依赖于其持久化机制和备份策略。以下是结合不同场景的恢复方法及原理&#xff1a; 一、通过持久化机制恢复数据 1. RDB&#xff08;Redis Database&#xff09;快照恢复 原理&#xff1a;RDB 通过生成内存数据的全量快照&#…...

【02】RUST项目(Cargo)

文章目录 rust项目与编译创建项目检查编译运行各级目录文件作用TODO各文件作用Cargo.tomlCargo.lockRUST项目一些关键字`mod``pub``use` (`as`)`pub use`重导出(re-exporting)`crate``suer`模块系统包 Pcakagescrate模块 Modules 和 usemain.rs的例子`lib.rs`的例子拆分文件为…...

二、通义灵码插件保姆级教学-IDEA(使用篇)

一、IntelliJ IDEA 中使用指南 1.1、代码解释 选择需要解释的代码 —> 右键 —> 通义灵码 —> 解释代码 解释代码很详细&#xff0c;感觉很强大有木有&#xff0c;关键还会生成流程图&#xff0c;对程序员理解业务非常有帮忙&#xff0c;基本能做到哪里不懂点哪里。…...

Docker使用指南与Dockerfile文件详解:从入门到实战

Docker使用指南与Dockerfile文件详解:从入门到实战 文章目录 **Docker使用指南与Dockerfile文件详解:从入门到实战****引言****第一部分:Docker 核心概念速览****1. Docker 基础架构****2. Docker 核心命令****第二部分:Dockerfile 文件深度解析****1. Dockerfile 是什么?…...

前端权限控制和管理

前端权限控制和管理 1.前言2.权限相关概念2.1权限的分类(1)后端权限(2)前端权限 2.2前端权限的意义 3.前端权限控制思路3.1菜单的权限控制3.2界面的权限控制3.3按钮的权限控制3.4接口的权限控制 4.实现步骤4.1菜单栏控制4.2界面的控制(1)路由导航守卫(2)动态路由 4.3按钮的控制…...

网络安全讲座之一:网络安全的重要性

第一讲内容主要对于安全的发展以及其重要性作了简明的阐述&#xff0c;并介绍了一些国内外知名的网络安全相关网站&#xff0c;并对于如何建立有效的安全策略给出了很好的建议&#xff0c;并让大家了解几种安全标准。   媒体经常报道一些有关网络安全威胁的令人震惊的事件&am…...