一个唯一的ID可以使用UUID,但不是顺序的。

一个自增的ID可以使用数据库序列、自增主键、雪花算法等等。

本文分享一个简单实用的一个ID生成代码,支持生成顺序自增且唯一的ID,一个工具类可以直接拷贝使用,简单、轻量。

原理:

ID组成规则: yyyyMMddHHmmssSSS + 自定义的位数(每秒并发数量)

生成逻辑:每毫秒时间戳开始加自定义的位数如4位 20220526111200000+0000,如果该时间内已经生成过该ID,那么自定义的位数自增1(20220526111200000+0001),即可认为每毫秒支持生成自定义位数的唯一ID(每毫秒多少并发)

代码如下:

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;public class UniqueSeqUtil {private static volatile int seq = 0;private static volatile long currentTimeMillis;public static class UniqueId {private final long currentTimeMillis;private final String id;private final String compensate;public UniqueId(long currentTimeMillis, String id, String compensate) {this.currentTimeMillis = currentTimeMillis;this.id = id;this.compensate = compensate;}/*** 生成该id时候的时间戳*/public long getCurrentTimeMillis() {return currentTimeMillis;}/*** 唯一ID*/public String getId() {return id;}/*** 补全的位,该时间戳的第几个*/public String getCompensate() {return compensate;}}/*** 生成一个唯一的订单序列,长度为 yyyyMMddHHmmssSSS + compensateI* * @param compensateI 4 代表长度加4位 ,支持每毫秒4位的并发* @return*/public final static synchronized UniqueId uniqueId(int compensateI) {final long ctm = System.currentTimeMillis();if (currentTimeMillis != ctm) {seq = 0;currentTimeMillis = ctm;}String compensate = "";// 补零String sqlStr = String.valueOf(++seq);int length = sqlStr.length();for (int i = 0; i < compensateI - length; i++) {compensate += "0";}String currentTimeStr = (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date(ctm));String id = currentTimeStr + compensate + sqlStr;return new UniqueId(ctm, id, compensate);}private static volatile long currentTimeMillis1;/*** 生成一个唯一序列yyyyMMddHHmmssSSS,延迟一毫秒生成,多线程调用那么串行*/public static String yyyyMMddHHmmssSSS() {long ctm;synchronized (UniqueSeqUtil.class) {while (true) {ctm = System.currentTimeMillis();if (currentTimeMillis1 != ctm) {currentTimeMillis1 = ctm;break;}}}String currentTimeStr = (new SimpleDateFormat("yyyyMMddHHmmssSSS")).format(new Date(ctm));return currentTimeStr;}}

测试该工具类生成ID是否安全,使用一个线程安全的Map去记录生成的ID,如果发现重复的ID那么就抛出异常

代码如下 :

public static void main(String[] args) {final Map<String,Integer> aa=new ConcurrentHashMap<String, Integer>();for (int i = 0; i < 50; i++) {new Thread(new Runnable() {@Overridepublic void run() {while (true) {String key = uniqueId(4).getId();if(aa.containsKey(key)) {throw new RuntimeException("重复");}else {aa.put(key, 1);System.out.println(key+"\t"+aa.size());}}}}).start();}}

执行结果:

测试发现生成速度还是很快的(具体读者可以自己测试,感觉一秒可以生成上万个ID),下图可以验证说明程序生成的ID是不会重复的(程序可靠)

总结:当然以上的程序性能并非是最优的,读者可以优化,若加上服务器ID号,就可以用来做分布式ID生成器,

如:ID规则 = 服务器ID + yyyyMMddHHmmssSSS + 自定义的位数(每秒并发数量)

订单号唯一ID顺序生成(一个轻量的实现)相关推荐

  1. 高并发分布式系统中生成全局唯一(订单号)Id

    2019独角兽企业重金招聘Python工程师标准>>> 高并发分布式系统中生成全局唯一(订单号)Id 1.GUID数据因毫无规律可言造成索引效率低下,影响了系统的性能,那么通过组合的 ...

  2. 多服务保证订单号唯一

    以生成订单号为例:多个用户下单时,如果我们只部署了一个服务,那么在订单生成的方法上使用 synchronized 可以保证订单号唯一,但是应用部署在多个服务器上时,用户访问不同服务器上的服务时,syn ...

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

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

  4. windows中常用的一个轻量的扫描软件xray_windows_amd64

    1.xray_windows_amd64现在windows中常用的一个轻量的扫描软件,用法要求各位同学通过物联网查找使用方式 完成对文章管理系统cms页面进行漏洞扫描. ①安装证书,在命令框xray_ ...

  5. 在 C++ 中实现一个轻量的标记清除 gc 系统

    在 C++ 中实现一个轻量的标记清除 gc 系统 最近想把 engine 做一个简单 C++ 封装,结合 QT 使用.engine 本身是用纯 C 实现的,大部分应用基于 lua 开发.对对象生命期管 ...

  6. 关于VSCode中工作区的讲解与使用工作区还你一个轻量 的VSCode

    VSCode的使用率在逐渐提高,但安装太多的插件会使得VSCode变得臃肿,甚至运行变慢,占用太多内存,此文章介绍了工作区,并如何来使用工作区更好地体验VSCode. 初次使用VSCode,肯定有很多 ...

  7. Javalin:一个轻量的 Web Framework

    说起 Java 语言下的 Web 框架那就非 Spring Framework 不可了,但是今天在和别人在聊天的过程中发现了一个新奇的项目 Javalin.Javalin 是一个轻量的 Web 框架. ...

  8. 我们开源了一个轻量的 Web IDE UI 框架 - Molecule

    Molecule , 一个轻量的 Web IDE UI 框架 https://github.com/DTStack/molecule​github.com/DTStack/molecule 简介 Mo ...

  9. Multipass - 一个轻量虚拟机管理器

    Multipass 是一个轻量虚拟机管理器,是由 Ubuntu 运营公司 Canonical 所推出的开源项目.运行环境支持 Linux.Windows.macOS.在不同的操作系统上,使用的是不同的 ...

最新文章

  1. python微信自动机器人
  2. 从零开始学python网络爬虫-从零开始学Python网络爬虫 PDF 下载
  3. mysql备份与还原
  4. c sqlserver建表csdn_Oracle拉出在sqlserver建表的语句
  5. 提问的智慧 如何得到好的帮助(转)
  6. dotnet Blazor 用 C# 控制界面行为
  7. echarts字变大_在echarts中如何调整lable的字体大小?
  8. 前端基础进阶(七):函数与函数式编程
  9. leetcode 480. 滑动窗口中位数(堆+滑动窗口)
  10. 网站域名解析端口_环境测试必备,无需注册域名,免费动态IP解析一键解析本地网站...
  11. matlab 计算 工程,matlab工程计算.doc
  12. 自由读写配置文件的艺术[java c++ node](二)
  13. java socket 全双工_java socket实现全双工通信
  14. mongodb 系列 ~ mongo的两种引擎对比
  15. 一文带你看懂自然语言处理——word表示技术的变迁(从bool模型到BERT)
  16. mysql实现周月表_Mysql,Mybatis做时间过滤报表:日周月统计
  17. 计算机显示没有可以的ip地址,电脑连不上WiFi,手机可以访问,出现黄色感叹号,没有有效的ip配置...
  18. php判断0点到7点凌晨时间段的方法
  19. Linux之scp命令的介绍以及命令行输入密码参数执行方法和常见问题解决
  20. 计算机类专业教指委委员名单,教育部高等学校计算机类专业教学指导委员会举办《高校计算机系统能力培养教学研讨会》...

热门文章

  1. 天嵌A40I平台如何调试10.1寸MIPI屏?这份总结收好!
  2. 麒麟信安电力行业信创解决方案获评首届长沙智慧城市“优秀解决方案”
  3. 怎样把mkv文件转成mp4?
  4. 《计算机操作》实训报告,计算机操作统实训报告.doc
  5. 台词生成器 (html5 版)
  6. 2017新零售元年?总是快人一步的乐语已经走向好零售
  7. C# 实现多张图片合成一张gif(录屏可能会用到)
  8. 【vue 项目】表单正则表达式校验1-32位,中文、英文、数字及特殊字符_-,必须以中文或英文字符开头等
  9. 边缘计算那些事儿--网络切片技术(1)
  10. 教你如何在C++里锁电脑的屏!