hutool工具包 中的雪花算法Snowflake 获取Long类型id 或者String 类型id(全局唯一id解决方案)

这篇具有很好参考价值的文章主要介绍了hutool工具包 中的雪花算法Snowflake 获取Long类型id 或者String 类型id(全局唯一id解决方案)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1.引入pom依赖

		<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-core</artifactId>
            <version>5.6.5</version>
        </dependency>

2.源码

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package cn.hutool.core.lang;

import cn.hutool.core.date.SystemClock;
import cn.hutool.core.util.StrUtil;
import java.io.Serializable;
import java.util.Date;

public class Snowflake implements Serializable {
    private static final long serialVersionUID = 1L;
    private final long twepoch;
    private final long workerIdBits;
    private final long maxWorkerId;
    private final long dataCenterIdBits;
    private final long maxDataCenterId;
    private final long sequenceBits;
    private final long workerIdShift;
    private final long dataCenterIdShift;
    private final long timestampLeftShift;
    private final long sequenceMask;
    private final long workerId;
    private final long dataCenterId;
    private final boolean useSystemClock;
    private long sequence;//序列号
    private long lastTimestamp;  //上一次时间戳

    public Snowflake(long workerId, long dataCenterId) {
        this(workerId, dataCenterId, false);
    }

    public Snowflake(long workerId, long dataCenterId, boolean isUseSystemClock) {
        this((Date)null, workerId, dataCenterId, isUseSystemClock);
    }

    public Snowflake(Date epochDate, long workerId, long dataCenterId, boolean isUseSystemClock) {
        this.workerIdBits = 5L;
        this.maxWorkerId = 31L;
        this.dataCenterIdBits = 5L;
        this.maxDataCenterId = 31L;
        this.sequenceBits = 12L;
        this.workerIdShift = 12L;
        this.dataCenterIdShift = 17L;
        this.timestampLeftShift = 22L;
        this.sequenceMask = 4095L;
        this.sequence = 0L;
        this.lastTimestamp = -1L;
        if (null != epochDate) {
            this.twepoch = epochDate.getTime();
        } else {
            this.twepoch = 1288834974657L;
        }

        if (workerId <= 31L && workerId >= 0L) {
            if (dataCenterId <= 31L && dataCenterId >= 0L) {
                this.workerId = workerId;
                this.dataCenterId = dataCenterId;
                this.useSystemClock = isUseSystemClock;
            } else {
                throw new IllegalArgumentException(StrUtil.format("datacenter Id can't be greater than {} or less than 0", new Object[]{31L}));
            }
        } else {
            throw new IllegalArgumentException(StrUtil.format("worker Id can't be greater than {} or less than 0", new Object[]{31L}));
        }
    }

    public long getWorkerId(long id) {
        return id >> 12 & 31L;
    }

    public long getDataCenterId(long id) {
        return id >> 17 & 31L;
    }

    public long getGenerateDateTime(long id) {
        return (id >> 22 & 2199023255551L) + this.twepoch;
    }

	/**
     * 生成id
     */
    public synchronized long nextId() {
        long timestamp = this.genTime();
        //当前时间小如传入时间报错 拒绝生成id
        if (timestamp < this.lastTimestamp) {
            if (this.lastTimestamp - timestamp >= 2000L) {
                throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", new Object[]{this.lastTimestamp - timestamp}));
            }

            timestamp = this.lastTimestamp;
        }
			//相同毫秒内,序列号自增
        if (timestamp == this.lastTimestamp) {
            long sequence = this.sequence + 1L & 4095L;
            //同一毫秒的序列数已经达到最大
            if (sequence == 0L) {
                timestamp = this.tilNextMillis(this.lastTimestamp);
            }

            this.sequence = sequence;
        } else {
        	//不同毫秒内,序列号设置为0
            this.sequence = 0L;
        }

        this.lastTimestamp = timestamp;
        return timestamp - this.twepoch << 22   //时间戳部分,占41位 左移22位
        | this.dataCenterId << 17       //数据中心部分占5位,左移17位
        | this.workerId << 12          //机器标识部分占5位,左移10位         
        | this.sequence;               //序列号部分占12位
    }

    public String nextIdStr() {
        return Long.toString(this.nextId());
    }

    private long tilNextMillis(long lastTimestamp) {
        long timestamp;
        for(timestamp = this.genTime(); timestamp == lastTimestamp; timestamp = this.genTime()) {
        }

        if (timestamp < lastTimestamp) {
            throw new IllegalStateException(StrUtil.format("Clock moved backwards. Refusing to generate id for {}ms", new Object[]{lastTimestamp - timestamp}));
        } else {
            return timestamp;
        }
    }

    private long genTime() {
        return this.useSystemClock ? SystemClock.now() : System.currentTimeMillis();
    }
}

3. 注入 使用

@Service
@Slf4j
public class XxxServiceImpl implements XxxServive {
		@Autowired
		private Snowflake snowflake;
		
		public AxxRspDTO save(AxxReqDTO reqDTO) {
			
		//获取Long类型id
		Long id = snowflake.nextId();
		//获取sring类型id
		String id = snowflake.nextIdStr();
		
		}
}

4优缺点:

1.优点:
毫秒数在高位,自增序列在低位,整个ID都是趋势递增的。
不依赖数据库等第三方系统,以服务的方式部署,稳定性更高,生成ID的性能也是非常高的。
可以根据自身业务特性分配bit位,非常灵活。
2.缺点:
依赖机器时钟,如果机器时钟回拨,会导致重复ID生成
在单机上是递增的,但是由于设计到分布式环境,每台机器上的时钟不可能完全同步,有时候会出现不是全局递增的情况
(此缺点可以认为无所谓,一般分布式ID只要求趋势递增,并不会严格要求递增,90%的需求都只要求趋势递增)

文章来源地址https://www.toymoban.com/news/detail-619986.html

到了这里,关于hutool工具包 中的雪花算法Snowflake 获取Long类型id 或者String 类型id(全局唯一id解决方案)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 雪花算法SnowFlake 细致易懂 Java/Springboot实现

    分布式中生成唯一性ID的一种算法 。 为啥不用数据库的自增主键呢? 唯一性: 如果数据库数据特别多,你会同一张表建立不同节点上,数据也在不同节点上存,那么如果俩ID都是 001 违背主键 定义吗? 顺序性: 雪花算法计算出来ID 有顺序 如果你了解数据库 B+树 ,对于索引来

    2024年04月22日
    浏览(25)
  • C# 分布式自增ID算法snowflake(雪花算法)

    分布式系统中,有一些需要使用全局唯一 ID 的场景,这种时候为了防止 ID 冲突可以使用36位的 UUID ,但是 UUID 有一些缺点,首先他相对比较长,另外 UUID 一般是无序的。有些时候我们希望能使用一种简单一些的 ID ,并且希望 ID 能够按照时间有序生成。而 Twitter 的 snowflake 解

    2024年04月10日
    浏览(34)
  • 仪酷LabVIEW AI视觉工具包及开放神经网络交互工具包常见问题解答

    哈喽,各位朋友,好久不见~ 之前给大家分享了基于LabVIEW开发的AI视觉工具包及开放神经网络交互工具包,不少朋友私信说在安装和使用过程中会遇到一些问题,今天我们就集中回复一下大家问到最多的问题。如果大家在使用过程中还有其他问题,可以补充到评论区,我们这

    2024年02月16日
    浏览(57)
  • GIS工具包

    GIS工具包,根据jts工具,结合实际使用场景提取出来的常用工具集合;涵盖几何格式转换(WKT,GeoJSON等)与geometry转换、gis距离计算、度距离单位换算、角度计算、buffer运算、映射截取、几何穿串等操作 gis-tools源码库地址 1.1 WktTool使用说明 wkt格式与geometry互转; wkt转geometry操作

    2024年02月06日
    浏览(68)
  • 学习笔记-JVM-工具包(JVM分析工具)

    常用工具 JDK工具 ① jps: JVM Process status tool:JVM进程状态工具,查看进程基本信息 ② jstat: JVM statistics monitoring tool : JVM统计监控工具,查看堆,GC详细信息 ③ jinfo:Java Configuration Info :查看配置参数信息,支持部分参数运行时修改 ④ jmap:Java Memory Map :分析堆内存工具,du

    2024年02月13日
    浏览(55)
  • MATLAB添加工具包(详细)

    我这里要添加的文件包为:DeepLearnToolbox-master 我这里的安装目录是:D:softwareMATLABtoolbox (1)以中文版为例,在主界面找到“设置路径”按钮 (2)点击“设置路径”,弹出设置界面 第一步:点“添加文件夹” (注:如果要工具包中有多个子文件夹,则点“添加并包含子文

    2024年02月02日
    浏览(65)
  • 掌握MySQL分库分表(六)解决主键重复问题--Snowflake雪花算法

    单库下⼀般使用Mysql自增ID,但是分库分表后,会造成不同分片上的数据表主键会重复 需求:性能强劲、全局唯一、防止恶意用户规矩id的规则来获取数据 利用自增id, 设置不同的⾃增步长: auto_increment_offset 、 auto-increment-increment 缺点: 依靠数据库系统的功能实现,但是未来

    2024年02月09日
    浏览(34)
  • Windows11渗透工具包分享

              项目地址 下载地址

    2024年02月13日
    浏览(58)
  • Hardhat工具包1--安装使用

    参考资料: 官方文档 : https://hardhat.org/getting-started/ https://hardhat.org/hardhat-runner/docs/getting-started#overview 基于Hardhat和Openzeppelin开发可升级合约(一) 基于Hardhat和Openzeppelin开发可升级合约(一)_灬倪先森_的博客-CSDN博客 ---------------------------------------------------------------------------------

    2023年04月11日
    浏览(106)
  • Quanto: PyTorch 量化工具包

    量化技术通过用低精度数据类型 (如 8 位整型 (int8)) 来表示深度学习模型的权重和激活,以减少传统深度学习模型使用 32 位浮点 (float32) 表示权重和激活所带来的计算和内存开销。 减少位宽意味着模型的内存占用更低,这对在消费设备上部署大语言模型至关重要。量化技术也

    2024年04月10日
    浏览(77)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包