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

多线程压测方法模板

主要步骤

  • 创建一个线程池

    ExecutorService service = Executors.newFixedThreadPool(20);
    
  • 创建任务

    Runnable task = () -> {// 具体实现
    };
    
  • 提交多个任务到线程池

    for (int i = 0; i < 100000; i++) {service.submit(task);
    }
    
  • 关闭线程池

    service.shutdown();
    
  • 等待所有任务完成

    service.awaitTermination(1, TimeUnit.MINUTES);
    

示例一

以下是一个示例,使用多线程验证 IdGeneratorgenerateId 方法的准确性,测试其并发场景下是否会生成重复的 id。

import java.util.concurrent.*;
import java.util.*;public class Test {public static void main(String[] args) throws InterruptedException {// 创建一个线程池ExecutorService service = Executors.newFixedThreadPool(10);// 创建一个用于存储生成的 ID 的集合Set<String> idSet = Collections.synchronizedSet(new HashSet<>());// 创建一个名为 IdGenerator 的类,其中包含一个 generateId 方法class IdGenerator {String generateId() {// 在这里实现你的 ID 生成逻辑return UUID.randomUUID().toString();}}IdGenerator generator = new IdGenerator();// 创建一个任务,该任务调用 ID 生成方法并将结果添加到集合中Runnable task = () -> {String id = generator.generateId();if (idSet.contains(id)) {System.out.println("重复的 ID: " + id);} else {idSet.add(id);}};// 提交多个任务到线程池for (int i = 0; i < 10000; i++) {service.submit(task);}// 关闭线程池service.shutdown();// 等待所有任务完成service.awaitTermination(1, TimeUnit.MINUTES);System.out.println("生成的 ID 数量: " + idSet.size());}
}

这个程序会创建一个固定大小的线程池,并提交多个任务到线程池。每个任务都会调用 generateId 方法并将生成的 ID 添加到一个集合中。如果生成的 ID 已经存在于集合中,那么程序会打印出重复的 ID。最后,程序会打印出生成的 ID 的数量。

请注意,这只是一个基本的示例,你可能需要根据你的具体需求进行修改。例如,你可能需要调整线程池的大小任务的数量,或者 generateId 方法的实现。此外,如果你的 generateId 方法不是线程安全的,你可能需要添加适当的同步机制。如果你的 generateId 方法可能抛出异常,你可能需要添加适当的错误处理代码。最后,你可能需要添加更多的逻辑来更详细地检查生成的 ID(例如,检查 ID 的格式或长度)

示例二

首先,假设你的 ID 生成方法如下:

public class IdGenerator {public synchronized String generateUniqueId() {// 这里是生成唯一 ID 的逻辑,这里只是一个示例return UUID.randomUUID().toString();}
}

然后,编写测试类和测试方法:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.HashSet;
import java.util.Set;public class IdGeneratorTest {private static final IdGenerator idGenerator = new IdGenerator();private static final int THREAD_COUNT = 100; // 线程数量private static final int ID_COUNT = 1000; // 每个线程生成的 ID 数量public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);Set<String> allIds = new HashSet<>(); // 用于存储所有生成的 ID,以检查重复// 提交任务到线程池for (int i = 0; i < THREAD_COUNT; i++) {Runnable worker = new IdGeneratorTask(allIds, ID_COUNT);executorService.submit(worker);}// 所有任务完成之前,主线程等待executorService.shutdown();if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {System.out.println("一些任务未完成执行。");} else {System.out.println("所有 ID 已生成并检查完毕。");}// 检查是否有重复的 IDif (allIds.size() == THREAD_COUNT * ID_COUNT) {System.out.println("测试通过:没有发现重复的 ID。");} else {System.out.println("测试失败:发现了重复的 ID。");}}static class IdGeneratorTask implements Runnable {private final Set<String> allIds;private final int idCount;public IdGeneratorTask(Set<String> allIds, int idCount) {this.allIds = allIds;this.idCount = idCount;}@Overridepublic void run() {for (int i = 0; i < idCount; i++) {String id = idGenerator.generateUniqueId();synchronized (allIds) {if (!allIds.add(id)) {System.out.println("发现重复的 ID: " + id);}}}}}
}

这个程序创建了一个 IdGenerator 类,其中包含一个同步方法 generateUniqueId 用于生成 ID。IdGeneratorTest 类中的 main 方法设置了一个线程池,并提交了多个任务到线程池中。每个任务都是生成指定数量的 ID 并将它们添加到一个共享的 HashSet 中。使用 HashSet 是因为它不允许重复元素,如果尝试添加重复的 ID,add 方法将返回 false 并打印出重复的 ID。

请注意,这个示例使用了 UUID 作为 ID 生成方法,它几乎可以保证全局唯一性。如果你使用的是其他类型的 ID 生成算法,你需要确保它在多线程环境下的线程安全性。

我们还可以对程序进行一些改进,程序中使用 synchronized 关键字来同步对 allIds 集合的访问,这可能会导致性能瓶颈。我们可以使用 ConcurrentHashMap 来替代 HashSet,因为 ConcurrentHashMap 也能保证线程安全,并且性能更好。

下面是改进后的程序:

import java.util.concurrent.*;
import java.util.Map;
import java.util.UUID;public class IdGenerator {public String generateUniqueId() {// 假设这里是你的 ID 生成逻辑return UUID.randomUUID().toString();}
}public class IdGeneratorTest {private static final IdGenerator idGenerator = new IdGenerator();private static final int THREAD_COUNT = 100; // 线程数量private static final int ID_COUNT = 1000; // 每个线程生成的 ID 数量private static final Map<String, Integer> idCounts = new ConcurrentHashMap<>();public static void main(String[] args) throws InterruptedException {ExecutorService executorService = Executors.newFixedThreadPool(THREAD_COUNT);// 提交任务到线程池for (int i = 0; i < THREAD_COUNT; i++) {executorService.submit(new IdGeneratorTask());}executorService.shutdown();if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) {System.out.println("一些任务未完成执行。");} else {System.out.println("所有 ID 已生成并检查完毕。");checkForDuplicates();}}static class IdGeneratorTask implements Runnable {@Overridepublic void run() {for (int i = 0; i < ID_COUNT; i++) {String id = idGenerator.generateUniqueId();int count = idCounts.getOrDefault(id, 0) + 1;idCounts.put(id, count);}}}private static void checkForDuplicates() {idCounts.forEach((id, count) -> {if (count > 1) {System.out.printf("发现重复的 ID: %s (重复次数: %d)%n", id, count);}});}
}

在这个改进的程序中,我们使用了 ConcurrentHashMap 来记录每个 ID 的出现次数。如果某个 ID 的出现次数大于 1,说明它是重复的,程序将打印出具体的重复 ID 及其重复次数。

请注意,这个示例使用了 UUID 作为 ID 生成方法,它几乎可以保证全局唯一性。如果你的 ID 生成算法不是基于 UUID,那么你需要确保它在多线程环境下的线程安全性。此外,awaitTermination 方法的超时时间根据实际情况进行调整。

真实案例

错误的 generateId 方法实现:

synchronized String generateId() {// 在这里实现你的 ID 生成逻辑// 有问题的实现(并发场景下)Random random = new Random();Integer number = random.nextInt(9000) + 1000;SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");return sdf.format(new Date()) + String.valueOf(number);
}

改进的 generateId 方法实现:

synchronized String generateId() {// 在这里实现你的 ID 生成逻辑// 改进的实现:String dateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));Duration duration = Duration.between(LocalTime.of(0, 0, 0), LocalTime.now());String secondsOfTimeStr = StringUtils.leftPad(String.valueOf(duration.getSeconds()), 5, "0");String key = dateStr + secondsOfTimeStr;String value = redisTemplate.opsForValue().get(key);if (null == value) {value = redisTemplate.opsForValue().increment(key).toString();redisTemplate.expire(key, 60L, TimeUnit.SECONDS);} else {value = redisTemplate.opsForValue().increment(key).toString();}String x = key + StringUtils.leftPad(value, 4, "0");return x;
}

至此,over~

相关文章:

多线程压测方法模板

主要步骤 创建一个线程池 ExecutorService service Executors.newFixedThreadPool(20);创建任务 Runnable task () -> {// 具体实现 };提交多个任务到线程池 for (int i 0; i < 100000; i) {service.submit(task); }关闭线程池 service.shutdown();等待所有任务完成 s…...

Uniapp软件库全新带勋章功能(包含前后端源码)

源码介绍&#xff1a; Uniapp开发的软件库全新带勋章功能&#xff0c;搭建好后台 在前端找到 util 这个文件 把两个js文件上面的填上自己的域名&#xff0c;电脑需要下载&#xff1a;HBuilderX 登录账号 没有账号就注册账号&#xff0c; 然后上传文件&#xff0c;打包选择 “…...

秋招突击——7/5——设计模式知识点补充——适配器模式、代理模式和装饰器模式

文章目录 引言正文适配器模式学习篮球翻译适配器 面试题 代理模式学习面试题 装饰器模式学习装饰模式总结 面试题 总结 引言 为了一雪前耻&#xff0c;之前腾讯面试的极其差&#xff0c;设计模式一点都不会&#xff0c;这里找了一点设计模式的面试题&#xff0c;就针对几个常考…...

bmob Harmony鸿蒙快速开发搜索功能

搜索功能是很多应用都需要的功能。在很多平台上&#xff0c;要开发一个兼容性较好的搜索功能都还是需要添加比较多的视图代码的。 为了解决这个问题&#xff0c;鸿蒙ArkUI提供了一个快速添加搜索功能的视图组件给我们&#xff0c;结合Bmob Harmony鸿蒙SDK的搜索能力&#xff0…...

软通动力子公司鸿湖万联最新成果SwanLink AI亮相世界人工智能大会

7月4日&#xff0c;2024世界人工智能大会暨人工智能全球治理高级别会议&#xff08;WAIC 2024&#xff09;在上海拉开帷幕&#xff0c;软通动力董事长兼首席执行官刘天文受邀出席开幕式。其间&#xff0c;软通动力携子公司鸿湖万联深度参与到大会各项活动中&#xff0c;并全面展…...

查看Linux系统中日志文件

Linux 系统中 Ubuntu&#xff0c;Debian&#xff0c;CentOS&#xff0c;RedHat 作为常用的服务器软件系统&#xff0c;很多人都已经熟知。不论是服务器出现问题&#xff0c;还是日常维护或各种环境搭建&#xff0c;我们经常需要登录上服务器查看日志。 如果熟知 Linux 下的 ta…...

技术干货|如何轻松完成空调管路的随机振动分析以及疲劳寿命预测

基于NVHD 的虚拟路面谱激励车内结构路噪优化 作者&#xff1a;戴相花 颜磊 吕霞 杨凯 单位&#xff1a;苏州三星电子有限公司 论文摘要 随机振动试验是评估空调管路流通振动耐久性的重要试验之一。本文以某型号空调管路系统为研究对象&#xff0c;评估空调管路随机振动疲劳…...

中英双语介绍中国的城市:上海市(Shanghai)

中文版 上海市是中国最大的城市之一&#xff0c;也是全球重要的金融、贸易和航运中心。作为一座现代化的国际大都市&#xff0c;上海以其繁华的商业区、丰富的文化遗产和多样化的经济结构而闻名。以下是对上海市的详细介绍&#xff0c;包括其地理位置、人口、经济、教育、文化…...

代码随想录算法训练营第75天:总结篇[1]

代码随想录算法训练营第75天&#xff1a;总结篇 代码随想录姑且是都过了一遍了&#xff0c;最开始了解到的时候还不会c语法&#xff0c;跟着学习还是有难度的&#xff0c;也很难坚持着去写题&#xff0c;后面决定加入训练营与大家齐头并进&#xff0c;刚开始气氛很好&#xff…...

眼动追踪技术 | 眼动的分类和模型

摘要 灵长类动物用于调整中央凹位置的正常眼动&#xff0c;几乎都可以归结为五种基本类型的组合&#xff1a;扫视、平稳追踪、聚散、前庭眼震和生理性眼震(与注视相关的微小运动)。聚散运动用于将双眼聚焦于远处的目标(深度知觉)。其他运动(如适应和聚焦)指的是眼动的非位置变…...

如何使用PHP根据输入文字动态调整图片尺寸?

根据文字改变图片尺寸的PHP代码 以下是一个使用PHP实现根据输入的文字动态调整图片尺寸的示例代码。该代码使用GD库来处理图片。 1. 创建HTML表单 首先&#xff0c;我们需要一个HTML表单来接受用户输入的文字和新的图片尺寸。 <!DOCTYPE html> <html lang"en…...

3.js - hdr贴图 是什么,有什么用

HDR贴图&#xff1a;High-Dynamic Range&#xff08;高动态范围&#xff09;贴图 一、定义与特点 定义&#xff1a;HDR贴图是具有高动态范围的环境贴图&#xff0c;能够捕捉并保留丰富的亮部细节和暗部细节&#xff0c;从而模拟出更加真实的光照效果。特点&#xff1a; 高动态…...

Nature Communications|用于电子皮肤的自主自愈晶体管(柔性半导体器件/电子皮肤/柔性电子)

2024年4月23日,韩国庆熙大学Jin Young Oh,美国斯坦福大学鲍哲南(Zhenan Bao)和韩国嘉泉大学Tae Il Lee团队,在《Nature Communications》上发布了一篇题为“Autonomous self-healing supramolecular polymer transistors for skin electronics”的论文。论文内容如下: 一…...

6月30日功能测试Day10

3.4.4拼团购测试点 功能位置&#xff1a;营销-----拼团购 后台优惠促销列表管理可以添加拼团&#xff0c;查看拼团活动&#xff0c;启动活动&#xff0c;编辑活动&#xff0c;删除活动。 可以查看拼团活动中已下单的订单以状态 需求分析 功能和添加拼团 商品拼团活动页 3…...

无人机对地面运动目标定位---获取目标的移动方向和速度

目录 一、引子 我们利用单目无人机通过等时间间隔拍照的形式对地面某移动目标进行定位&#xff0c;当前&#xff0c;我们已经获得了每张相片上该目标的三维坐标&#xff0c;并且知道该无人机在飞行过程中拍照的时间间隔&#xff0c;那么我们就可以通过一定的计算&#xff0c;得…...

管理才是最根本的核心竞争力

相信大家对于华为提出的“管理是核心竞争力”“管理才是企业的核心竞争力”等言论并不陌生&#xff0c;而华为的确也一直践行这样的理念。比如&#xff0c;在华为发展历史上很艰难的2002年&#xff0c;华为仍然坚持重点抓管理。总裁任正非后来提到&#xff1a;“2002年华为快崩…...

Raid阵列中硬盘损坏后,新硬盘可以直接换上吗?

RAID更换的方式基本类似&#xff0c;这里以RAID 1为例。 1. 关闭服务器&#xff1a;确保服务器或RAID控制器处于关闭或已停止状态&#xff0c;以避免数据写入或损坏。确定损坏硬盘&#xff1a;通过RAID控制器的管理界面&#xff0c;确定哪一块硬盘在RAID 中损坏。 2. 拆卸原硬…...

Python爬虫康复训练——笔趣阁《神魂至尊》

还是话不多说&#xff0c;很久没写爬虫了&#xff0c;来个bs4康复训练爬虫&#xff0c;正好我最近在看《神魂至尊》&#xff0c;爬个txt文件下来看看 直接上代码 """ 神魂至尊网址-https://www.bqgui.cc/book/1519/ """ import requests from b…...

Kaptcha验证码

Kaptcha验证码 Kaptcha 是一个用于生成验证码的开源库&#xff0c;在 Java 中使用它可以轻松地为应用程序添加验证码功能。 一、引入依赖 首先&#xff0c;需要在项目的 pom.xml 文件&#xff08;如果是 Maven 项目&#xff09;中添加 Kaptcha 的依赖&#xff1a; <depend…...

Rufus 制作启动盘 | 便携的工作空间

唠唠闲话 最近服务器硬盘故障多&#xff0c;在修复过程中&#xff0c;学习了一些操作&#xff0c;这里做个记录。本期主要介绍 U盘启动盘的制作&#xff0c;以及持久化存储。 U 盘启动盘 镜像选择 Ubuntu 的版本命名遵循 “Adjective Animal” 的模式&#xff0c;即 “形容…...

后进先出(LIFO)详解

LIFO 是 Last In, First Out 的缩写&#xff0c;中文译为后进先出。这是一种数据结构的工作原则&#xff0c;类似于一摞盘子或一叠书本&#xff1a; 最后放进去的元素最先出来 -想象往筒状容器里放盘子&#xff1a; &#xff08;1&#xff09;你放进的最后一个盘子&#xff08…...

shell脚本--常见案例

1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件&#xff1a; 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

电脑插入多块移动硬盘后经常出现卡顿和蓝屏

当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时&#xff0c;可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案&#xff1a; 1. 检查电源供电问题 问题原因&#xff1a;多块移动硬盘同时运行可能导致USB接口供电不足&#x…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

cf2117E

原题链接&#xff1a;https://codeforces.com/contest/2117/problem/E 题目背景&#xff1a; 给定两个数组a,b&#xff0c;可以执行多次以下操作&#xff1a;选择 i (1 < i < n - 1)&#xff0c;并设置 或&#xff0c;也可以在执行上述操作前执行一次删除任意 和 。求…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...