JAVA如何利用Lock实现多线程并发生成唯一的流水号

article/2025/11/8 16:32:21

本文记录在开发过程,JAVA如何利用ReentrantLock实现多线程并发生成唯一的流水号。


  在实际的开发中,我们会经常碰到需要生成唯一流水号的业务场景。有些情况可以采用数据库自定义序列号自增生成流水号,亦或是自己编写数据库触发器生成流水号。但本文以代码实操为主,记录在代码层面上如何利用ReentrantLock,实现多线程同时请求时也能确保流水号取得唯一的场景。
  ReentrantLock锁原理在本文中不再阐述,详细的讲解可参考此文:https://blog.csdn.net/zhengzhaoyang122/article/details/110847701


一、编写流水号的生成类

   ReentrantLock锁的运用其实很简单,在方法中如下添加即可,简单的调用业务前先上锁,调用完后释放锁。这里我采用简单的年月日+流水的规则生成流水号。

public class GetSerialNum {/**记录已有流水单*/public static int num = 0;private static ReentrantLock lock = new ReentrantLock();public static String getNum() {String unique = "";//上锁lock.lock();try {//------------------流水号业务逻辑----------------//5位流水号if (num == 0) {//当天第一份流水单号unique = new SimpleDateFormat("yyyyMMdd").format(new Date()) + "01";} else {//当天最后的订单流水号累加1String nums = String.valueOf(num + 1);//设定具体流水为两位数,单数则补齐前面的0StringBuilder sb = new StringBuilder(nums);for (int i = nums.length(); i < 2; i++) {sb.insert(0, "0");}unique = new SimpleDateFormat("yyyyMMdd").format(new Date()) + sb.toString();}//已有流水单+1num++;//----------------------------------} catch (Exception e) {e.printStackTrace();} finally {//释放锁lock.unlock();}return "TEST" + unique;}
}

二、编写测试样例验证

  这里我们利用CyclicBarrier类来模仿进行大量并发的测试。CyclicBarrier是JDK1.5的java.util.concurrent并发包中提供的一个并发工具类。

1.准备一个Task线程类。

public class Task implements Runnable {private static final Logger logger = Logger.getLogger("log");private CyclicBarrier cyclicBarrier;public Task(CyclicBarrier cyclicBarrier) {this.cyclicBarrier = cyclicBarrier;}@Overridepublic void run() {try {// 等待所有任务准备就绪cyclicBarrier.await();// 测试内容logger.info(GetSerialNum.getNum());} catch (Exception e) {e.printStackTrace();}}}

2.程序测试主入口,设定同时并发50个线程。

public class TestLock {public static void main(String[] args) {int count = 50;CyclicBarrier cyclicBarrier = new CyclicBarrier(count);ExecutorService executorService = Executors.newFixedThreadPool(count);for (int i = 0; i < count; i++) {executorService.execute(new Task(cyclicBarrier));}executorService.shutdown();while (!executorService.isTerminated()) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}
}

三、后台输出测试结果

  可以看到同一秒里,我们每条线程获取到的流水号都是唯一不重复的。

在这里插入图片描述


http://chatgpt.dhexx.cn/article/oWavrOSg.shtml

相关文章

mysql 生成流水号 存储过程 订单编号

用存储过程生成流水号是很常用的&#xff0c;这里以生成订单编号的流水号作为示例。&#xff08;新的一天的流水号从1开始&#xff0c;如&#xff1a;今天的订单编号是CD2013010900014&#xff0c;下一个订单编号将是CD2013010900015&#xff1b;明天的订单编号将从CD201301100…

流水号生成规则

流水号生成规则 从“0001”号起始&#xff0c;依序不跳跃不间断地编号&#xff0c;形成流水编码&#xff0c;依次为0001、0002、0003、0004、0005、0006…等。当编至“9999”号&#xff0c;仍需继续编号时&#xff0c;从“A000”号&#xff08;A000代表10000&#xff09;起始重…

一种生成流水号的方法

1.介绍 今天做了一个功能&#xff0c;生成订单流水号&#xff0c;当然这其实这并不是一个很难的功能&#xff0c;最直接的方式就是日期主机Id随机字符串来拼接一个流水号。但是今天有个我认为比较优雅方式来实现。我要介绍是日期 long&#xff08;商家Id订单类型主机IDAtomicIn…

简单介绍订单号或者流水号的生成方法

一般订单号或者流水号等可能在一些平台会用到&#xff0c;然后我就简单的介绍一个我自己生成订单号和流水号的一个方法吧&#xff0c;如果程序有问题或者你有更好的生成办法&#xff0c;欢迎留言&#xff0c;留下你的文章链接&#xff0c;我们一起学习和进步哈。 方法简介&…

如何使用redis生成流水号

概述 本文讲述如何使用redis生成流水号。本文是在Springboot中实现的。知道原理之后其他框架也可以轻松实现。 原理介绍 本文主要是使用redis的incr方法进行自增补零。然后结合时间、随机数、前缀组成唯一的流水号。 下面是流水号的结构。 在文章的最后还是简单介绍一下redis的…

谈谈订单号和流水号的关系

订单号和流水号是不同的。 首先订单号是订单唯一的编号&#xff0c;而且电商平台的各种子系统也是根据订单来统计业务完成的情况&#xff0c;订单编号经常用来被查询&#xff0c;所以数据类型必须是数字&#xff0c;而且是全局唯一&#xff0c;那肯定就得主键字段了。 然后流水…

低代码学习教程:生成固定格式流水号

方法1&#xff1a;RECNO()方法2&#xff1a;MAPX() 表单设计中经常涉及流水号的制作问题&#xff0c;下面就分别介绍下两种编号的实现方法&#xff0c;大家可以根据需要自行选择。 注意&#xff1a; 百数已支持【流水号】控件&#xff0c;如有特殊要求可参考文档&#xff1a;…

【26天高效学习Java编程】Day19:Java 多线程

本专栏将从基础开始&#xff0c;循序渐进&#xff0c;由浅入深讲解Java的基本使用&#xff0c;希望大家都能够从中有所收获&#xff0c;也请大家多多支持。 专栏地址:26天高效学习Java编程 相关软件地址:软件地址 所有代码地址:代码地址 如果文章知识点有错误的地方&#x…

怎么入门学习Java编程

因为目前java非常火,应用非常的广泛,是目前最火的行业之一,竞争很大,工资很高,未来发展也极好。 如条件还可以,负担不是那么大,可以选择培训,培训一定会比你自学的好,如果培训都学不好,自学肯定更难。目前java的培训费用都是2W+,这还只是培训费而已,加上一些其他的…

Java学习

集合 什么是集合&#xff1f; 集合&#xff1a;集合是java中提供的一种容器&#xff0c;可以用来存储多个数据。 集合和数组的区别 数组的长度是固定的。集合的长度是可变的。 数组中存储的是同一类型的元素&#xff0c;可以存储任意类型数据。集合存储的都是引用数据类型。如…

想学习Java编程,看书还是看视频更合适?

首先&#xff1a;自己本身就是初级或者零基础的&#xff0c;自己对软件了解的都不足够&#xff0c;跟着视频学&#xff0c;老师操作操作一步你就能看着他操作&#xff0c;这样心里更有谱。 第二&#xff1a;跟着视频学能学的更好&#xff0c;知识体系更全&#xff0c;一般视频…

自学过来人告诉你,初学者应该怎么快速的学习Java编程?

我说说我个人的案例吧&#xff0c;我电子信息专业&#xff0c;后来选择做了Java开发&#xff0c;在11年的时候开始学习的Java&#xff0c;可以说那时候的企业要求低于现在&#xff0c;我当时学习由于没有钱&#xff0c;我是自学的&#xff0c;我大学学过C语言 我晚上下班的时候…

通过项目驱动的学习方法快速掌握Java编程

摘要 Java作为一种广泛应用于软件开发领域的编程语言&#xff0c;对于零基础的学习者来说&#xff0c;学习Java编程可能存在一定的难度。本文将介绍如何通过项目驱动的学习方法&#xff0c;帮助零起点的学习者快速掌握Java编程。通过以项目为核心的学习路径、结合实践和理论的…

Java学习之编程入门

0 编程入门 0.1 概述0.2 计算机硬件介绍0.2.1 中央处理器0.2.2 存储设备0.2.3 内存0.2.4 输入和输出设备0.2.5 通信设备 0.3 计算机发展史上的鼻祖0.4 操作系统0.5 万维网0.6 职业发展与提升0.7 学习经验探讨 0.1 概述 计算机包括硬件(hardware)和软件(software)两部分。 硬件…

学习Java编程知识 必知要点

Java 是全球最受欢迎的编程语言之一&#xff0c;在世界编程语言排行榜 TIOBE 中&#xff0c;Java 一直霸占着前三名&#xff0c;有好多年甚至都是第一名。那么如此强大的Java你真的了解他的知识体系吗&#xff1f;他的学习路线你知道吗&#xff1f; 1. Java虚拟机——JVM JVM&a…

java三大平台介绍,选择哪个平台学习java编程?

&#x1f482; 个人主页: IT学习日记&#x1f91f; 版权: 本文由【IT学习日记】原创、在CSDN首发、需要转载请联系博主&#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦&#x1f485; 想寻找共同成长的小伙伴&#xff0c;请点击【技术圈子】 眼见…

学习java

Java 深度历险(作者成富&#xff0c;是IBM 中国软件开发中心的高级工程师) 2 目录 序 .................................................................................................................................. 1 目录 ................................…

Java怎么学习

入门的时候一定要搞清楚面向对象相关的概念 对象&#xff0c;类&#xff0c;实例&#xff0c;这三者的含义&#xff0c;还有三者之间有什么关系。 类之间的关系有那些<继承&#xff0c;聚合 组合&#xff0c;普通关联 自返关联>&#xff0c;关联的多重性&#xff0c;都…

Java:学习Java编程的主要技巧

随着互联网时代的发展&#xff0c;软件开发行业热度不断飙升&#xff0c;企业对软件开发人才需求量也与日俱增&#xff0c;尤以Java工程师为首&#xff0c;这也是一直以来Java培训日趋火热的原因。那么今天小编就和大家说说学Java编程的几个学习技巧 你精通基础知识吗? 掌握基…

JAVA编程入门学习

JAVA编程入门学习 本次学习内容&#xff1a; 1、Java初步讲解 2、Java运行环境的安装及应用 3、进行简单的Java编程 一、程序&#xff1a; 程序 算法 数据结构 用户使用编程语言实现问题域到解域的映射&#xff0c;细节描述算法。 1、编程语言——三大类&#xff1a;…