最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

使用雪花算法生成的 ID 具有以下特點:

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

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

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

public class Snowflake {

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

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

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

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

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

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

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

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

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

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

    /** 工作機器ID */
    private final long workerId;

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

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

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

    /**
     * 構(gòu)造函數(shù)
     * @param workerId 工作機器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不能超過%d且不能小于0", MAX_WORKER_ID));
        }
        if (dataCenterId > MAX_DATA_CENTER_ID || dataCenterId < 0) {
            throw new IllegalArgumentException(String.format("DataCenterID不能超過%d且不能小于0", MAX_DATA_CENTER_ID));
        }
        this.workerId = workerId;
        this.dataCenterId = dataCenterId;
    }

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

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

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

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

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

    /**
     * 等待下一毫秒
     * @param timestamp 上次生成ID的時間戳
     * @return 下一毫秒的時間戳
     */
    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());
    }
}

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

這是批量生成的ID:

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

相關文章

  • Spring Cloud 的 Hystrix.功能及實踐詳解

    Spring Cloud 的 Hystrix.功能及實踐詳解

    這篇文章主要介紹了Spring Cloud 的 Hystrix.功能及實踐詳解,Hystrix 具備服務降級、服務熔斷、線程和信號隔離、請求緩存、請求合并以及服務監(jiān)控等強大功能,需要的朋友可以參考下
    2019-07-07
  • Mybatis 如何批量刪除數(shù)據(jù)的實現(xiàn)示例

    Mybatis 如何批量刪除數(shù)據(jù)的實現(xiàn)示例

    這篇文章主要介紹了Mybatis 如何批量刪除數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-03-03
  • springboot接口返回數(shù)據(jù)類型全面解析

    springboot接口返回數(shù)據(jù)類型全面解析

    這篇文章主要介紹了springboot接口返回數(shù)據(jù)類型問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • IDEA如何配置本地tomcat啟動項目

    IDEA如何配置本地tomcat啟動項目

    這篇文章主要介紹了IDEA如何配置本地tomcat啟動項目問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • springboot整合TDengine全過程

    springboot整合TDengine全過程

    這篇文章主要介紹了springboot整合TDengine全過程,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • 編程入門:掌握Java運算符技巧

    編程入門:掌握Java運算符技巧

    掌握Java運算符技巧,能讓你的編程之旅輕松許多,本指南將帶你深入了解如何巧妙地使用這些強大的工具,讓代碼不僅高效,還充滿樂趣,跟著我們一起,讓你的Java代碼在運算符的魔法下煥發(fā)新生!
    2023-12-12
  • Spring security BCryptPasswordEncoder密碼驗證原理詳解

    Spring security BCryptPasswordEncoder密碼驗證原理詳解

    這篇文章主要介紹了Spring security BCryptPasswordEncoder密碼驗證原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法(兩種)

    Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法(兩種)

    這篇文章主要介紹了Java controller接口出入?yún)r間序列化轉(zhuǎn)換操作方法,本文給大家列舉兩種簡單方法,感興趣的朋友一起看看吧
    2025-04-04
  • IDEA配置Tomcat后,控制臺tomcat?catalina?log出現(xiàn)亂碼問題

    IDEA配置Tomcat后,控制臺tomcat?catalina?log出現(xiàn)亂碼問題

    本文介紹了如何通過設置Tomcat和IDEA的編碼格式來解決編碼問題,首先嘗試修改Tomcat的logging.properties文件中的編碼設置,如果未解決問題,則調(diào)整IDEA的編碼設置,通過修改vmoptions文件來全局設置IDEA的編碼格式,作者分享了個人成功解決問題的方法和步驟,供其他開發(fā)者參考
    2024-09-09
  • 如何使用Mockito調(diào)用靜態(tài)方法和void方法

    如何使用Mockito調(diào)用靜態(tài)方法和void方法

    這篇文章主要介紹了如何使用Mockito調(diào)用靜態(tài)方法和void方法的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評論

泸州市| 和龙市| 团风县| 伊春市| 越西县| 苏尼特右旗| 苏尼特左旗| 沈阳市| 利川市| 宾阳县| 延吉市| 隆安县| 丹寨县| 淳安县| 育儿| 阜城县| 泰宁县| 上林县| 得荣县| 思茅市| 萨迦县| 普兰店市| 鄄城县| 中宁县| 张家港市| 合川市| 栾川县| 阳春市| 平定县| 绵竹市| 樟树市| 邳州市| 合作市| 承德县| 达孜县| 安康市| 自贡市| 平湖市| 科尔| 库尔勒市| 读书|