多线程压测方法模板
主要步骤
-
创建一个线程池
ExecutorService service = Executors.newFixedThreadPool(20);
-
创建任务
Runnable task = () -> {// 具体实现 };
-
提交多个任务到线程池
for (int i = 0; i < 100000; i++) {service.submit(task); }
-
关闭线程池
service.shutdown();
-
等待所有任务完成
service.awaitTermination(1, TimeUnit.MINUTES);
示例一
以下是一个示例,使用多线程验证 IdGenerator
的 generateId
方法的准确性,测试其并发场景下是否会生成重复的 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软件库全新带勋章功能(包含前后端源码)
源码介绍: Uniapp开发的软件库全新带勋章功能,搭建好后台 在前端找到 util 这个文件 把两个js文件上面的填上自己的域名,电脑需要下载:HBuilderX 登录账号 没有账号就注册账号, 然后上传文件,打包选择 “…...

秋招突击——7/5——设计模式知识点补充——适配器模式、代理模式和装饰器模式
文章目录 引言正文适配器模式学习篮球翻译适配器 面试题 代理模式学习面试题 装饰器模式学习装饰模式总结 面试题 总结 引言 为了一雪前耻,之前腾讯面试的极其差,设计模式一点都不会,这里找了一点设计模式的面试题,就针对几个常考…...

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

软通动力子公司鸿湖万联最新成果SwanLink AI亮相世界人工智能大会
7月4日,2024世界人工智能大会暨人工智能全球治理高级别会议(WAIC 2024)在上海拉开帷幕,软通动力董事长兼首席执行官刘天文受邀出席开幕式。其间,软通动力携子公司鸿湖万联深度参与到大会各项活动中,并全面展…...
查看Linux系统中日志文件
Linux 系统中 Ubuntu,Debian,CentOS,RedHat 作为常用的服务器软件系统,很多人都已经熟知。不论是服务器出现问题,还是日常维护或各种环境搭建,我们经常需要登录上服务器查看日志。 如果熟知 Linux 下的 ta…...

技术干货|如何轻松完成空调管路的随机振动分析以及疲劳寿命预测
基于NVHD 的虚拟路面谱激励车内结构路噪优化 作者:戴相花 颜磊 吕霞 杨凯 单位:苏州三星电子有限公司 论文摘要 随机振动试验是评估空调管路流通振动耐久性的重要试验之一。本文以某型号空调管路系统为研究对象,评估空调管路随机振动疲劳…...
中英双语介绍中国的城市:上海市(Shanghai)
中文版 上海市是中国最大的城市之一,也是全球重要的金融、贸易和航运中心。作为一座现代化的国际大都市,上海以其繁华的商业区、丰富的文化遗产和多样化的经济结构而闻名。以下是对上海市的详细介绍,包括其地理位置、人口、经济、教育、文化…...
代码随想录算法训练营第75天:总结篇[1]
代码随想录算法训练营第75天:总结篇 代码随想录姑且是都过了一遍了,最开始了解到的时候还不会c语法,跟着学习还是有难度的,也很难坚持着去写题,后面决定加入训练营与大家齐头并进,刚开始气氛很好ÿ…...

眼动追踪技术 | 眼动的分类和模型
摘要 灵长类动物用于调整中央凹位置的正常眼动,几乎都可以归结为五种基本类型的组合:扫视、平稳追踪、聚散、前庭眼震和生理性眼震(与注视相关的微小运动)。聚散运动用于将双眼聚焦于远处的目标(深度知觉)。其他运动(如适应和聚焦)指的是眼动的非位置变…...
如何使用PHP根据输入文字动态调整图片尺寸?
根据文字改变图片尺寸的PHP代码 以下是一个使用PHP实现根据输入的文字动态调整图片尺寸的示例代码。该代码使用GD库来处理图片。 1. 创建HTML表单 首先,我们需要一个HTML表单来接受用户输入的文字和新的图片尺寸。 <!DOCTYPE html> <html lang"en…...
3.js - hdr贴图 是什么,有什么用
HDR贴图:High-Dynamic Range(高动态范围)贴图 一、定义与特点 定义:HDR贴图是具有高动态范围的环境贴图,能够捕捉并保留丰富的亮部细节和暗部细节,从而模拟出更加真实的光照效果。特点: 高动态…...

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拼团购测试点 功能位置:营销-----拼团购 后台优惠促销列表管理可以添加拼团,查看拼团活动,启动活动,编辑活动,删除活动。 可以查看拼团活动中已下单的订单以状态 需求分析 功能和添加拼团 商品拼团活动页 3…...

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

管理才是最根本的核心竞争力
相信大家对于华为提出的“管理是核心竞争力”“管理才是企业的核心竞争力”等言论并不陌生,而华为的确也一直践行这样的理念。比如,在华为发展历史上很艰难的2002年,华为仍然坚持重点抓管理。总裁任正非后来提到:“2002年华为快崩…...
Raid阵列中硬盘损坏后,新硬盘可以直接换上吗?
RAID更换的方式基本类似,这里以RAID 1为例。 1. 关闭服务器:确保服务器或RAID控制器处于关闭或已停止状态,以避免数据写入或损坏。确定损坏硬盘:通过RAID控制器的管理界面,确定哪一块硬盘在RAID 中损坏。 2. 拆卸原硬…...

Python爬虫康复训练——笔趣阁《神魂至尊》
还是话不多说,很久没写爬虫了,来个bs4康复训练爬虫,正好我最近在看《神魂至尊》,爬个txt文件下来看看 直接上代码 """ 神魂至尊网址-https://www.bqgui.cc/book/1519/ """ import requests from b…...
Kaptcha验证码
Kaptcha验证码 Kaptcha 是一个用于生成验证码的开源库,在 Java 中使用它可以轻松地为应用程序添加验证码功能。 一、引入依赖 首先,需要在项目的 pom.xml 文件(如果是 Maven 项目)中添加 Kaptcha 的依赖: <depend…...

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

第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

(十)学生端搭建
本次旨在将之前的已完成的部分功能进行拼装到学生端,同时完善学生端的构建。本次工作主要包括: 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...

376. Wiggle Subsequence
376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...

自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
汇编常见指令
汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX(不访问内存)XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

听写流程自动化实践,轻量级教育辅助
随着智能教育工具的发展,越来越多的传统学习方式正在被数字化、自动化所优化。听写作为语文、英语等学科中重要的基础训练形式,也迎来了更高效的解决方案。 这是一款轻量但功能强大的听写辅助工具。它是基于本地词库与可选在线语音引擎构建,…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...