欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java使用雪花算法生成唯一ID的實(shí)現(xiàn)示例

 更新時(shí)間:2024年07月09日 10:26:04   作者:小筱在線  
雪花算法是 Twitter 開(kāi)源的一種分布式ID生成算法,其目的是生成全局唯一的 ID,本文主要介紹了Java使用雪花算法生成唯一ID的實(shí)現(xiàn)示例,具有一定的參考價(jià)值,感興趣的可以了解一下

雪花算法(Snowflake ID)是 Twitter 開(kāi)源的一種分布式 ID 生成算法,其目的是生成全局唯一的 ID。該算法的核心思想是將一個(gè) 64 位的二進(jìn)制數(shù)字分成幾個(gè)部分,每個(gè)部分表示不同的信息,例如數(shù)據(jù)中心ID、機(jī)器ID、序列號(hào)等。這些部分的取值范圍可以根據(jù)實(shí)際情況進(jìn)行調(diào)整。

使用雪花算法生成的 ID 具有以下特點(diǎn):

  • 全局唯一,ID 不會(huì)重復(fù)。
  • 按時(shí)間有序,新生成的 ID 比舊的 ID 大。
  • 可以在分布式環(huán)境下生成,不需要中心節(jié)點(diǎn)協(xié)調(diào)。
  • 高性能,生成 ID 的速度快。

因其具有全局唯一和分布式特性,常被用于互聯(lián)網(wǎng)應(yīng)用的分布式系統(tǒng)中,如訂單號(hào)生成、數(shù)據(jù)庫(kù)主鍵生成等。

具體實(shí)現(xiàn)代碼如下:

public class Snowflake {

    /** 開(kāi)始時(shí)間戳 (2021-01-01) */
    private final long START_TIMESTAMP = 1609430400000L;

    /** 機(jī)器ID所占的位數(shù) */
    private final long WORKER_ID_BITS = 5L;

    /** 數(shù)據(jù)標(biāo)識(shí)ID所占的位數(shù) */
    private final long DATA_CENTER_ID_BITS = 5L;

    /** 支持的最大機(jī)器ID,結(jié)果是31 (0B11111) */
    private final long MAX_WORKER_ID = ~(-1L << WORKER_ID_BITS);

    /** 支持的最大數(shù)據(jù)標(biāo)識(shí)ID,結(jié)果是31 (0B11111) */
    private final long MAX_DATA_CENTER_ID = ~(-1L << DATA_CENTER_ID_BITS);

    /** 序列在ID中占的位數(shù) */
    private final long SEQUENCE_BITS = 12L;

    /** 機(jī)器ID向左移12位 */
    private final long WORKER_ID_SHIFT = SEQUENCE_BITS;

    /** 數(shù)據(jù)標(biāo)識(shí)ID向左移17位(12+5) */
    private final long DATA_CENTER_ID_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS;

    /** 時(shí)間戳向左移22位(5+5+12) */
    private final long TIMESTAMP_LEFT_SHIFT = SEQUENCE_BITS + WORKER_ID_BITS + DATA_CENTER_ID_BITS;

    /** 支持的最大序列號(hào),結(jié)果是4095 (0B111111111111) */
    private final long MAX_SEQUENCE = ~(-1L << SEQUENCE_BITS);

    /** 工作機(jī)器ID */
    private final long workerId;

    /** 數(shù)據(jù)中心ID */
    private final long dataCenterId;

    /** 毫秒內(nèi)序列號(hào) */
    private long sequence = 0L;

    /** 上次生成ID的時(shí)間戳 */
    private long lastTimestamp = -1L;

    /**
     * 構(gòu)造函數(shù)
     * @param workerId 工作機(jī)器ID
     * @param dataCenterId 數(shù)據(jù)中心ID
     */
    public Snowflake(long workerId, long dataCenterId) {
        if (workerId > MAX_WORKER_ID || workerId < 0) {
            throw new IllegalArgumentException(String.format("WorkerID不能超過(guò)%d且不能小于0", MAX_WORKER_ID));
        }
        if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
            throw new IllegalArgumentException(String.format("DataCenterID不能超過(guò)%d且不能小于0", MAX_DATA_CENTER_ID));
        }
        this.workerId = workerId;
        this.dataCenterId = dataCenterId;
    }

    /**
     * 生成ID
     * @return long類型的ID
     */
    public synchronized long nextId() {
        long timestamp = System.currentTimeMillis();

        // 如果當(dāng)前時(shí)間小于上次生成ID的時(shí)間戳,說(shuō)明系統(tǒng)時(shí)鐘回退過(guò),拋出異常
        if (timestamp < lastTimestamp) {
            throw new RuntimeException(String.format("系統(tǒng)時(shí)鐘回退,拒絕生成ID,上次生成ID的時(shí)間戳:%d,當(dāng)前時(shí)間戳:%d",
                    lastTimestamp, timestamp));
        }

        // 如果當(dāng)前時(shí)間等于上次生成ID的時(shí)間戳(同一毫秒內(nèi)),則序列號(hào)加1
        if (timestamp == lastTimestamp) {
            sequence = (sequence + 1) & MAX_SEQUENCE;
            if (sequence == 0) {
                // 如果序列號(hào)已經(jīng)超過(guò)最大值,需要等待到下一毫秒再繼續(xù)生成ID
                timestamp = waitNextMillis(timestamp);
            }
        } else {
            sequence = 0L;
        }

        // 更新上次生成ID的時(shí)間戳
        lastTimestamp = timestamp;

        // 生成ID
        return ((timestamp - START_TIMESTAMP) << TIMESTAMP_LEFT_SHIFT) |
                (dataCenterId << DATA_CENTER_ID_SHIFT) |
                (workerId << WORKER_ID_SHIFT) |
                sequence;
    }

    /**
     * 等待下一毫秒
     * @param timestamp 上次生成ID的時(shí)間戳
     * @return 下一毫秒的時(shí)間戳
     */
    private long waitNextMillis(long timestamp) {
        long nextTimestamp = System.currentTimeMillis();
        while (nextTimestamp <= timestamp) {
            nextTimestamp = System.currentTimeMillis();
        }
        return nextTimestamp;
    }

    // 示例
    public static void main(String[] args) {
        Snowflake snowflake = new Snowflake(1, 1);
        System.out.println(snowflake.nextId());
    }
}

在上述代碼中,可以通過(guò)調(diào)整START_TIMESTAMP、WORKER_ID_BITS、DATA_CENTER_ID_BITS、SEQUENCE_BITS等參數(shù)來(lái)滿足不同的需求,例如支持更多的機(jī)器、更高的QPS等。

這是批量生成的ID:

到此這篇關(guān)于Java使用雪花算法生成唯一ID的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Java 雪花算法生成唯一ID內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • Spring gateway + Oauth2實(shí)現(xiàn)單點(diǎn)登錄及詳細(xì)配置

    Spring gateway + Oauth2實(shí)現(xiàn)單點(diǎn)登錄及詳細(xì)配置

    gateway是基于 WebFlux的響應(yīng)式編程框架,所以在使用securityConfig時(shí)采用的注解是@EnableWebFluxSecurity,接下來(lái)通過(guò)本文給大家介紹Spring gateway + Oauth2實(shí)現(xiàn)單點(diǎn)登錄及詳細(xì)配置,感興趣的朋友一起看看吧
    2021-09-09
  • rabbitmq的消息持久化處理開(kāi)啟,再關(guān)閉后,消費(fèi)者啟動(dòng)報(bào)錯(cuò)問(wèn)題

    rabbitmq的消息持久化處理開(kāi)啟,再關(guān)閉后,消費(fèi)者啟動(dòng)報(bào)錯(cuò)問(wèn)題

    這篇文章主要介紹了rabbitmq的消息持久化處理開(kāi)啟,再關(guān)閉后,消費(fèi)者啟動(dòng)報(bào)錯(cuò)問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Springboot+jwt實(shí)現(xiàn)在線用戶功能(示例代碼)

    Springboot+jwt實(shí)現(xiàn)在線用戶功能(示例代碼)

    這篇文章主要介紹了Springboot+jwt實(shí)現(xiàn)在線用戶功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-12-12
  • Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)

    Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié)

    這篇文章主要為大家介紹了Java批量向PDF文件中添加圖像水印實(shí)現(xiàn)細(xì)節(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-05-05
  • 詳細(xì)SpringBoot生命周期接口的使用

    詳細(xì)SpringBoot生命周期接口的使用

    本文主要介紹了SpringBoot生命周期接口的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • 基于JPA中的@Basic注解詳解

    基于JPA中的@Basic注解詳解

    這篇文章主要介紹了JPA中的@Basic注解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java中的LinkedHashMap詳解

    Java中的LinkedHashMap詳解

    這篇文章主要介紹了Java中的LinkedHashMap詳解,LinkedHashMap繼承自HashMap,它的多種操作都是建立在HashMap操作的基礎(chǔ)上的,同HashMap不同的是,LinkedHashMap維護(hù)了一個(gè)Entry的雙向鏈表,保證了插入的Entry中的順序,需要的朋友可以參考下
    2023-09-09
  • 使用@slf4j找不到符號(hào)log的問(wèn)題及解決

    使用@slf4j找不到符號(hào)log的問(wèn)題及解決

    這篇文章主要介紹了使用@slf4j找不到符號(hào)log的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 多線程(多窗口賣票實(shí)例講解)

    多線程(多窗口賣票實(shí)例講解)

    下面小編就為大家?guī)?lái)一篇多線程(多窗口賣票實(shí)例講解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Java實(shí)戰(zhàn)之敏感詞過(guò)濾器

    Java實(shí)戰(zhàn)之敏感詞過(guò)濾器

    這篇文章主要介紹了Java實(shí)戰(zhàn)之敏感詞過(guò)濾器,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04

最新評(píng)論