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

java中雪花算法時鐘回?fù)軉栴}解決

 更新時間:2024年10月30日 11:11:47   作者:需要重新演唱  
本文介紹了分布式系統(tǒng)中使用雪花算法生成唯一ID時可能遇到的時鐘回?fù)軉栴},以及解決這個問題的幾種方法,包括等待機制、擴展位、預(yù)留時間戳或邏輯時鐘等,感興趣的可以了解一下

雪花算法(Snowflake)是Twitter開源的一種分布式唯一ID生成算法,用于在分布式系統(tǒng)中生成全局唯一的ID。雪花算法生成的ID是一個64位的整數(shù),通常表示為長整型(long)。

雪花算法的結(jié)構(gòu)

雪花算法生成的ID由以下幾部分組成:

  • 符號位(1位):始終為0,保證生成的ID為正數(shù)。
  • 時間戳(41位):記錄生成ID的時間戳,精確到毫秒級。可以使用大約69年的時間。
  • 機器ID(10位):標(biāo)識生成ID的機器,可以支持1024臺機器。
  • 序列號(12位):同一毫秒內(nèi)生成的多個ID的序列號,可以支持每毫秒生成4096個ID。

時鐘回?fù)軉栴}

時鐘回?fù)軉栴}是指在分布式系統(tǒng)中,由于各種原因(如NTP時間同步),某些節(jié)點的系統(tǒng)時間可能會回退到過去的時間點。這會導(dǎo)致雪花算法生成的ID出現(xiàn)重復(fù),因為時間戳部分會重復(fù)。

解決時鐘回?fù)軉栴}的方法

  • 等待機制

    • 當(dāng)檢測到時鐘回?fù)軙r,生成器可以等待時間追上上次生成ID的時間戳,然后再生成新的ID。這種方法簡單直接,但可能會導(dǎo)致生成器在等待期間無法生成新的ID。
  • 擴展位

    • 在ID結(jié)構(gòu)中增加額外的位來處理時鐘回?fù)?。例如,可以使用額外的位來記錄時鐘回?fù)艿拇螖?shù),從而避免ID重復(fù)。
  • 預(yù)留時間戳

    • 在生成ID時,預(yù)留一些時間戳范圍,用于處理時鐘回?fù)?。例如,可以預(yù)留一些時間戳范圍,當(dāng)檢測到時鐘回?fù)軙r,使用預(yù)留的時間戳生成新的ID。
  • 邏輯時鐘

    • 使用邏輯時鐘(如Lamport時鐘或Vector時鐘)代替物理時鐘。邏輯時鐘可以保證在分布式系統(tǒng)中事件的順序,避免時鐘回?fù)軉栴}。

示例代碼

以下是一個使用等待機制解決時鐘回?fù)軉栴}的雪花算法實現(xiàn)示例:

public class SnowflakeIdGenerator {
    private final long twepoch = 1288834974657L; // 起始時間戳,例如Twitter的Snowflake起始時間
    private final long workerIdBits = 10L;
    private final long maxWorkerId = -1L ^ (-1L << workerIdBits);
    private final long sequenceBits = 12L;
    private final long workerIdShift = sequenceBits;
    private final long timestampLeftShift = sequenceBits + workerIdBits;
    private final long sequenceMask = -1L ^ (-1L << sequenceBits);

    private long workerId;
    private long sequence = 0L;
    private long lastTimestamp = -1L;

    public SnowflakeIdGenerator(long workerId) {
        if (workerId > maxWorkerId || workerId < 0) {
            throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));
        }
        this.workerId = workerId;
    }

    public synchronized long nextId() {
        long timestamp = timeGen();

        if (timestamp < lastTimestamp) {
            // 時鐘回?fù)?,等待時間追上
            long offset = lastTimestamp - timestamp;
            if (offset <= 5) {
                try {
                    wait(offset << 1);
                    timestamp = timeGen();
                    if (timestamp < lastTimestamp) {
                        throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
                    }
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            } else {
                throw new RuntimeException(String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", offset));
            }
        }

        if (lastTimestamp == timestamp) {
            sequence = (sequence + 1) & sequenceMask;
            if (sequence == 0) {
                timestamp = tilNextMillis(lastTimestamp);
            }
        } else {
            sequence = 0L;
        }

        lastTimestamp = timestamp;

        return ((timestamp - twepoch) << timestampLeftShift) |
                (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 idGenerator = new SnowflakeIdGenerator(1);
        System.out.println(idGenerator.nextId());
    }
}

代碼解釋

  • 檢測時鐘回?fù)?/strong>:

    • 在生成ID時,首先獲取當(dāng)前時間戳,并與上次生成ID的時間戳進行比較。
    • 如果當(dāng)前時間戳小于上次生成ID的時間戳,說明發(fā)生了時鐘回?fù)堋?/li>
  • 等待機制

    • 如果時鐘回?fù)艿臅r間差小于等于5毫秒,生成器會等待時間追上上次生成ID的時間戳。
    • 如果時鐘回?fù)艿臅r間差大于5毫秒,拋出異常,拒絕生成ID。
  • 生成新的ID

    • 如果時鐘沒有回?fù)?,或者等待時間追上后,生成新的ID。

總結(jié)

時鐘回?fù)軉栴}是分布式系統(tǒng)中使用雪花算法生成唯一ID時需要解決的一個重要問題。通過使用等待機制、擴展位、預(yù)留時間戳或邏輯時鐘等方法,可以有效避免時鐘回?fù)軐?dǎo)致的ID重復(fù)問題。在實際應(yīng)用中,可以根據(jù)具體需求選擇合適的解決方案。

到此這篇關(guān)于java中雪花算法時鐘回?fù)軉栴}解決的文章就介紹到這了,更多相關(guān)java 雪花算法時鐘回?fù)軆?nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中調(diào)用SQL Server存儲過程詳解

    Java中調(diào)用SQL Server存儲過程詳解

    這篇文章主要介紹了Java中調(diào)用SQL Server存儲過程詳解,本文講解了使用不帶參數(shù)的存儲過程、使用帶有輸入?yún)?shù)的存儲過程、使用帶有輸出參數(shù)的存儲過程、使用帶有返回狀態(tài)的存儲過程、使用帶有更新計數(shù)的存儲過程等操作實例,需要的朋友可以參考下
    2015-01-01
  • Java Spring事務(wù)使用及驗證過程詳解

    Java Spring事務(wù)使用及驗證過程詳解

    這篇文章主要介紹了Java Spring事務(wù)使用及驗證過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • java如何去除圖片中的白色背景

    java如何去除圖片中的白色背景

    這篇文章主要為大家詳細介紹了java去除圖片中白色背景的方法,教大家如何將圖片中的白色背景去掉,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04
  • 參數(shù)校驗Spring的@Valid注解用法解析

    參數(shù)校驗Spring的@Valid注解用法解析

    這篇文章主要介紹了參數(shù)校驗Spring的@Valid注解用法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • SpringBoot集成xxl-job實現(xiàn)超牛的定時任務(wù)的步驟詳解

    SpringBoot集成xxl-job實現(xiàn)超牛的定時任務(wù)的步驟詳解

    XXL-JOB是一個分布式任務(wù)調(diào)度平臺,其核心設(shè)計目標(biāo)是開發(fā)迅速、學(xué)習(xí)簡單、輕量級、易擴展,現(xiàn)已開放源代碼并接入多家公司線上產(chǎn)品線,開箱即用,本文給大家介紹了SpringBoot集成xxl-job實現(xiàn)超牛的定時任務(wù),需要的朋友可以參考下
    2023-10-10
  • 使用jenv工具管理多個JDK版本的方法步驟

    使用jenv工具管理多個JDK版本的方法步驟

    jenv是一個開源的?Java?環(huán)境管理工具,旨在幫助開發(fā)者在同一臺機器上輕松管理和切換多個Java版本,這篇文章主要介紹了使用jenv工具管理多個JDK版本的方法步驟,需要的朋友可以參考下
    2025-06-06
  • 老生常談java中的數(shù)組初始化

    老生常談java中的數(shù)組初始化

    下面小編就為大家?guī)硪黄仙U刯ava中的數(shù)組初始化。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Java 實戰(zhàn)項目之誠途旅游系統(tǒng)的實現(xiàn)流程

    Java 實戰(zhàn)項目之誠途旅游系統(tǒng)的實現(xiàn)流程

    讀萬卷書不如行萬里路,只學(xué)書上的理論是遠遠不夠的,只有在實戰(zhàn)中才能獲得能力的提升,本篇文章手把手帶你用java+SpringBoot+Vue+maven+Mysql實現(xiàn)一個精美的物流管理系統(tǒng),大家可以在過程中查缺補漏,提升水平
    2021-11-11
  • 微信公眾號開發(fā)消息推送功能

    微信公眾號開發(fā)消息推送功能

    微信公眾號分為服務(wù)號、訂閱號、企業(yè)號,訂閱號可以個人申請,服務(wù)號和企業(yè)號要有企業(yè)資質(zhì)才可以,這篇文章主要介紹了微信公眾號開發(fā)消息推送功能,需要的朋友可以參考下
    2023-02-02
  • java實現(xiàn)線程阻塞式方法

    java實現(xiàn)線程阻塞式方法

    Java阻塞式方法會使線程暫停執(zhí)行,不占用CPU資源直至條件滿足,常見阻塞方法如Thread.sleep()、Object.wait()和I/O操作,具有一定的參考價值,感興趣的可以了解一下
    2024-10-10

最新評論

丹棱县| 南宫市| 永泰县| 农安县| 沙田区| 盐源县| 墨脱县| 丹巴县| 西吉县| 通化县| 宁武县| 平乡县| 旬邑县| 揭东县| 灵山县| 晴隆县| 南康市| 勃利县| 山西省| 天水市| 四川省| 长乐市| 内丘县| 松滋市| 怀化市| 桦甸市| 洪江市| 伊宁县| 射阳县| 马山县| 白水县| 睢宁县| 上思县| 枣庄市| 合江县| 长顺县| 嘉峪关市| 西宁市| 搜索| 沾化县| 大理市|