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

Java?通過手寫分布式雪花SnowFlake生成ID方法詳解

 更新時(shí)間:2022年04月07日 16:47:05   作者:田埂、  
SnowFlake是twitter公司內(nèi)部分布式項(xiàng)目采用的ID生成算法,開源后廣受國內(nèi)大廠的好評。由這種算法生成的ID,我們就叫做SnowFlakeID,下面我們來詳細(xì)看看

SnowFlake算法

SnowFlake算法生成id的結(jié)果是一個(gè)64bit大小的整數(shù),它的結(jié)構(gòu)如下圖:

在這里插入圖片描述

分為四段:

第一段: 1位為未使用,永遠(yuǎn)固定為0。

(因?yàn)槎M(jìn)制中最高位是符號位,1表示負(fù)數(shù),0表示正數(shù)。生成的id一般都是用正整數(shù),所以最高位固定為0 )

第二段: 41位為毫秒級時(shí)間(41位的長度可以使用69年)

第三段: 10位為workerId(10位的長度最多支持部署1024個(gè)節(jié)點(diǎn))

(這里的10位又分為兩部分,第一部分5位表示數(shù)據(jù)中心ID(0-31)第二部分5位表示機(jī)器ID(0-31))

第四段: 12位為毫秒內(nèi)的計(jì)數(shù)(12位的計(jì)數(shù)順序號支持每個(gè)節(jié)點(diǎn)每毫秒產(chǎn)生4096個(gè)ID序號)

代碼實(shí)現(xiàn):

import java.util.HashSet;
import java.util.concurrent.atomic.AtomicLong;

public class SnowFlake {

    //時(shí)間 41位
    private static long lastTime = System.currentTimeMillis();

    //數(shù)據(jù)中心ID 5位(默認(rèn)0-31)
    private long datacenterId = 0;
    private long datacenterIdShift = 5;

    //機(jī)房機(jī)器ID 5位(默認(rèn)0-31)
    private long workerId = 0;
    private long workerIdShift = 5;

    //隨機(jī)數(shù) 12位(默認(rèn)0~4095)
    private AtomicLong random = new AtomicLong();
    private long randomShift = 12;
    //隨機(jī)數(shù)的最大值
    private long maxRandom = (long) Math.pow(2, randomShift);

    public SnowFlake() {
    }

    public SnowFlake(long workerIdShift, long datacenterIdShift){
        if (workerIdShift < 0 ||
                datacenterIdShift < 0 ||
                workerIdShift + datacenterIdShift > 22) {
            throw new IllegalArgumentException("參數(shù)不匹配");
        }
        this.workerIdShift = workerIdShift;
        this.datacenterIdShift = datacenterIdShift;
        this.randomShift = 22 - datacenterIdShift - workerIdShift;
        this.maxRandom = (long) Math.pow(2, randomShift);
    }

    //獲取雪花的ID
    private long getId() {
        return lastTime << (workerIdShift + datacenterIdShift + randomShift) |
                workerId << (datacenterIdShift + randomShift) |
                datacenterId << randomShift |
                random.get();
    }

    //生成一個(gè)新的ID
    public synchronized long nextId() {
        long now = System.currentTimeMillis();

        //如果當(dāng)前時(shí)間和上一次時(shí)間不在同一毫秒內(nèi),直接返回
        if (now > lastTime) {
            lastTime = now;
            random.set(0);
            return getId();
        }

	//將最后的隨機(jī)數(shù),進(jìn)行+1操作
        if (random.incrementAndGet() < maxRandom) {
            return getId();
        }

        //自選等待下一毫秒
        while (now <= lastTime) {
            now = System.currentTimeMillis();
        }

        lastTime = now;
        random.set(0);
        return getId();

    }

    //測試
    public static void main(String[] args) {
        SnowFlake snowFlake = new SnowFlake();
        HashSet<Long> set = new HashSet<>();
        for (int i = 0; i < 10000; i++) {
            set.add(snowFlake.nextId());
        }
        System.out.println(set.size());
    }

}

代碼中獲取id的方法利用位運(yùn)算實(shí)現(xiàn)

在這里插入圖片描述

 1  |                    41                        |  5  |   5  |     12      

   0|0001100 10100010 10111110 10001001 01011100 00|00000|0 0000|0000 00000000 //41位的時(shí)間

   0|000000?0 00000000 00000000 00000000 00000000 00|10001|0 0000|0000 00000000 //5位的數(shù)據(jù)中心ID

   0|0000000 00000000 00000000 00000000 00000000 00|00000|1 1001|0000 00000000 //5為的機(jī)器ID

or 0|0000000 00000000 00000000 00000000 00000000 00|00000|0 0000|?0000 00000000? //12位的sequence

------------------------------------------------------------------------------------------

   0|0001100 10100010 10111110 10001001 01011100 00|10001|1 1001|?0000 00000000? //結(jié)果:910499571847892992

SnowFlake優(yōu)點(diǎn)

所有生成的id按時(shí)間趨勢遞增

整個(gè)分布式系統(tǒng)內(nèi)不會(huì)產(chǎn)生重復(fù)id(因?yàn)橛衐atacenterId和workerId來做區(qū)分)

SnowFlake不足

由于SnowFlake強(qiáng)依賴時(shí)間戳,所以時(shí)間的變動(dòng)會(huì)造成SnowFlake的算法產(chǎn)生錯(cuò)誤。

到此這篇關(guān)于Java 通過手寫分布式雪花SnowFlake生成ID方法詳解的文章就介紹到這了,更多相關(guān)Java SnowFlake內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解Java類動(dòng)態(tài)加載和熱替換

    詳解Java類動(dòng)態(tài)加載和熱替換

    本文主要介紹類加載器、自定義類加載器及類的加載和卸載等內(nèi)容,并舉例介紹了Java類的熱替換。
    2021-05-05
  • Java中HttpServletRequestWrapper的使用與原理詳解

    Java中HttpServletRequestWrapper的使用與原理詳解

    這篇文章主要介紹了Java中HttpServletRequestWrapper的使用與原理詳解,HttpServletRequestWrapper 實(shí)現(xiàn)了 HttpServletRequest 接口,可以讓開發(fā)人員很方便的改造發(fā)送給 Servlet 的請求,需要的朋友可以參考下
    2024-01-01
  • springboot docker原理及項(xiàng)目構(gòu)建

    springboot docker原理及項(xiàng)目構(gòu)建

    這篇文章主要介紹了springboot docker原理及項(xiàng)目構(gòu)建,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • SpringBoot整合分布式鎖redisson的示例代碼

    SpringBoot整合分布式鎖redisson的示例代碼

    這篇文章主要介紹了SpringBoot整合分布式鎖redisson,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • 通過web控制當(dāng)前的SpringBoot程序重新啟動(dòng)

    通過web控制當(dāng)前的SpringBoot程序重新啟動(dòng)

    本文主要給大家介紹了如何通過web控制當(dāng)前的SpringBoot程序重新啟動(dòng),文章給出了詳細(xì)的代碼示例供大家參考,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-11-11
  • IDEA 單元測試創(chuàng)建方法詳解(2020.03版本親測)

    IDEA 單元測試創(chuàng)建方法詳解(2020.03版本親測)

    這篇文章主要介紹了IDEA 單元測試創(chuàng)建方法詳解(2020.03版本親測),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • 使用Java DOM解析器修改XML文件內(nèi)容的操作方法

    使用Java DOM解析器修改XML文件內(nèi)容的操作方法

    在Java中,XML文件的解析和修改可以通過多種方法實(shí)現(xiàn),其中DOM(Document Object Model)是一種常用的方式,在本文中,我們將介紹如何使用Java DOM解析器修改XML文件中的內(nèi)容,并給出一個(gè)具體的示例,需要的朋友可以參考下
    2024-08-08
  • SpringBoot中controller深層詳細(xì)講解

    SpringBoot中controller深層詳細(xì)講解

    這篇文章主要介紹了SpringBoot在Controller層接收參數(shù)的常用方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • java字符串拼接與性能分析詳解

    java字符串拼接與性能分析詳解

    在JAVA中拼接兩個(gè)字符串的最簡便的方式就是使用操作符”+”。如果你用”+”來連接固定長度的字符串,可能性能上會(huì)稍受影響,但是如果你是在循環(huán)中來”+”多個(gè)串的話,性能將指數(shù)倍的下降,下面我們分析一下JAVA字符串拼接的性能
    2014-01-01
  • Java8新特性:Lambda表達(dá)式之方法引用詳解

    Java8新特性:Lambda表達(dá)式之方法引用詳解

    這篇文章主要給大家介紹了關(guān)于Java8新特性:Lambda表達(dá)式之方法引用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評論

揭东县| 上栗县| 博客| 林口县| 榕江县| 麻阳| 米脂县| 苍山县| 夏邑县| 巢湖市| 龙泉市| 德州市| 军事| 安岳县| 灵台县| 三门峡市| 巴塘县| 安国市| 宁德市| 射阳县| 合山市| 鄂温| 甘德县| 高邮市| 白沙| 固镇县| 神农架林区| 巫山县| 内丘县| 普陀区| 浦县| 普洱| 二手房| 尤溪县| 保山市| 南靖县| 长阳| 仁化县| 中超| 永兴县| 临夏县|