SpringBoot自定義雪花算法生成ID的實(shí)現(xiàn)示例
雪花算法(Snowflake)是一種生成唯一ID的分布式算法,由Twitter推出。它能生成不重復(fù)的、有時(shí)間順序的全局唯一ID。一個(gè)典型的Snowflake ID由64位組成,通常劃分如下:
- 1位符號(hào)位(始終為0,表示正數(shù))
- 41位時(shí)間戳(毫秒級(jí),表示當(dāng)前時(shí)間相對于某個(gè)開始時(shí)間的偏移)
- 10位機(jī)器標(biāo)識(shí)(通常分為數(shù)據(jù)中心ID和機(jī)器ID)
- 12位序列號(hào)(表示毫秒內(nèi)的計(jì)數(shù)器)
下面是一個(gè)自定義的雪花算法來生成唯一的ID。這個(gè)實(shí)現(xiàn)類似于Twitter的Snowflake算法,并考慮到了線程安全。
public class SnowflakeIDGenerator { // 起始時(shí)間戳(2020-01-01 00:00:00) private final long twepoch = 1577836800000L; // 每部分占用的位數(shù) private final long workerIdBits = 5L; private final long datacenterIdBits = 5L; private final long sequenceBits = 12L; // 最大值 private final long maxWorkerId = -1L ^ (-1L << workerIdBits); private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); // 位移 private final long workerIdShift = sequenceBits; private final long datacenterIdShift = sequenceBits + workerIdBits; private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; // 掩碼 private final long sequenceMask = -1L ^ (-1L << sequenceBits); private long workerId; private long datacenterId; private long sequence = 0L; private long lastTimestamp = -1L; public SnowflakeIDGenerator(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId)); } if (datacenterId > maxDatacenterId || datacenterId < 0) { throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId)); } this.workerId = workerId; this.datacenterId = datacenterId; } public synchronized long nextId() { long timestamp = timeGen(); if (timestamp < lastTimestamp) { throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp)); } if (lastTimestamp == timestamp) { sequence = (sequence + 1) & sequenceMask; if (sequence == 0) { timestamp = tilNextMillis(lastTimestamp); } } else { sequence = 0L; } lastTimestamp = timestamp; return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence; } protected long tilNextMillis(long lastTimestamp) { long timestamp = timeGen(); while (timestamp <= lastTimestamp) { timestamp = timeGen(); } return timestamp; } protected long timeGen() { return System.currentTimeMillis(); } public static void main(String[] args) { SnowflakeIDGenerator generator = new SnowflakeIDGenerator(1, 1); for (int i = 0; i < 10; i++) { System.out.println(generator.nextId()); } } }
說明
初始化參數(shù):
twepoch
:自定義的起始時(shí)間戳(可以是任意過去的時(shí)間),確保生成的ID是唯一且有序的。workerIdBits
和datacenterIdBits
:分別表示工作節(jié)點(diǎn)ID和數(shù)據(jù)中心ID的位數(shù)(通常為5位)。sequenceBits
:表示序列號(hào)的位數(shù)(通常為12位)。
最大值計(jì)算:
maxWorkerId
和maxDatacenterId
:根據(jù)位數(shù)計(jì)算出的最大值,確保ID在合理范圍內(nèi)。
位移量:
workerIdShift
,datacenterIdShift
,timestampLeftShift
:用于將各部分?jǐn)?shù)據(jù)移到正確的位置。
掩碼:
sequenceMask
:確保序列號(hào)在0到4095之間循環(huán)。
方法:
nextId
:生成唯一ID,使用同步塊確保線程安全。tilNextMillis
:等待直到下一毫秒。timeGen
:獲取當(dāng)前時(shí)間戳。
使用示例
運(yùn)行上述代碼,你會(huì)看到生成的唯一ID,它們是按時(shí)間順序遞增的,每個(gè)ID包含了時(shí)間戳、數(shù)據(jù)中心ID、工作節(jié)點(diǎn)ID和序列號(hào)的信息。
到此這篇關(guān)于SpringBoot自定義雪花算法生成ID的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot 雪花算法生成ID內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringMVC數(shù)據(jù)輸出相關(guān)知識(shí)總結(jié)
今天帶大家學(xué)習(xí)SpringMVC的相關(guān)知識(shí),文中對SpringMVC數(shù)據(jù)輸出作了非常詳細(xì)的代碼示例,對正在學(xué)習(xí)的小伙伴們很有幫助,需要的朋友可以參考下2021-06-06Spring Boot Admin微服務(wù)應(yīng)用監(jiān)控的實(shí)現(xiàn)
這篇文章主要介紹了Spring Boot Admin微服務(wù)應(yīng)用監(jiān)控,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10spring security獲取用戶信息為null或者串值的解決
這篇文章主要介紹了spring security獲取用戶信息為null或者串值的解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03ssm框架Springmvc文件上傳實(shí)現(xiàn)代碼詳解
這篇文章主要介紹了ssm框架Springmvc文件上傳實(shí)現(xiàn)代碼詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07idea打開項(xiàng)目后無法顯示目錄結(jié)構(gòu),只能顯示.iml文件問題
這篇文章主要介紹了idea打開項(xiàng)目后無法顯示目錄結(jié)構(gòu),只能顯示.iml文件問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08BMIDE環(huán)境導(dǎo)入項(xiàng)目報(bào)編碼錯(cuò)誤解決方案
這篇文章主要介紹了BMIDE環(huán)境導(dǎo)入項(xiàng)目報(bào)編碼錯(cuò)誤解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10Java編程之多線程死鎖與線程間通信簡單實(shí)現(xiàn)代碼
這篇文章主要介紹了Java編程之多線程死鎖與線程間通信簡單實(shí)現(xiàn)代碼,具有一定參考價(jià)值,需要的朋友可以了解下。2017-10-10