Heim > Java > javaLernprogramm > So generieren Sie eine ID durch handschriftliche verteilte Schneeflocken-SnowFlake in Java

So generieren Sie eine ID durch handschriftliche verteilte Schneeflocken-SnowFlake in Java

PHPz
Freigeben: 2023-04-24 21:34:16
nach vorne
1080 Leute haben es durchsucht

SnowFlake-Algorithmus

Das Ergebnis der vom SnowFlake-Algorithmus generierten ID ist eine 64-Bit-Ganzzahl. Seine Struktur ist wie folgt:

So generieren Sie eine ID durch handschriftliche verteilte Schneeflocken-SnowFlake in Java

ist in vier Abschnitte unterteilt:

Erster Abschnitt: 1 Bit ist unbenutzt und ist immer auf 0 festgelegt.

(Da das höchste Bit im Binärformat das Vorzeichenbit ist, stellt 1 eine negative Zahl und 0 eine positive Zahl dar. Die generierten IDs sind im Allgemeinen positive Ganzzahlen, daher ist das höchste Bit auf 0 festgelegt)

Zweiter Absatz: 41 Bits sind Millisekunden-Zeiten (die Länge von 41 Bits kann 69 Jahre lang verwendet werden)

Der dritte Absatz: 10 Bits ist die Worker-ID (die Länge von 10 Bits unterstützt die Bereitstellung von bis zu 1024 Knoten)

(Die 10 Bits hier sind in zwei Teile unterteilt, der erste Teil wird durch 5 Bits dargestellt. Der 5-stellige zweite Teil der Rechenzentrums-ID (0-31) stellt die Maschinen-ID (0-31) dar)

Der vierte Absatz: 12-Bit-Anzahl innerhalb von Millisekunden (die 12-Bit-Zählsequenznummer unterstützt jeden Knoten, der 4096 pro Millisekunde ID-Seriennummer generiert)

Code-Implementierung:

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

public class SnowFlake {

    //时间 41位
    private static long lastTime = System.currentTimeMillis();

    //数据中心ID 5位(默认0-31)
    private long datacenterId = 0;
    private long datacenterIdShift = 5;

    //机房机器ID 5位(默认0-31)
    private long workerId = 0;
    private long workerIdShift = 5;

    //随机数 12位(默认0~4095)
    private AtomicLong random = new AtomicLong();
    private long randomShift = 12;
    //随机数的最大值
    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("参数不匹配");
        }
        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();
    }

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

        //如果当前时间和上一次时间不在同一毫秒内,直接返回
        if (now > lastTime) {
            lastTime = now;
            random.set(0);
            return getId();
        }

	//将最后的随机数,进行+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());
    }

}
Nach dem Login kopieren

Die Methode zum Erhalten der ID im Code wird mithilfe von Bitoperationen implementiert

So generieren Sie eine ID durch handschriftliche verteilte Schneeflocken-SnowFlake in Java

1 12 00000 00000000 00000000 00000000 00|10001|0 0000|0000 00000000 //5-stellige Daten Zentrums-ID

0|0000000 00000000 00000000 00000000 00000000 00|. 00000|1 1001|0000 00000000 //5-Bit-Maschinen-ID

oder 0|0000000 00000000 00000000 00000000 00000000 00|00000|0 0000|0000 00000000 //12 Ziffern Reihenfolge

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

0|0001100 10100010 10111110 10001001 01011100 00|10001|1 1001|. 0000 00000000 //Ergebnis: 910499571847892992

SnowFlake Vorteile:

Alle generierten IDs steigen entsprechend dem Zeittrend. Im gesamten verteilten System werden keine doppelten IDs generiert (da solche vorhanden sind). datacenterId und workerId zur Unterscheidung) SnowFlake-Nachteile:

Da SnowFlake stark auf Zeitstempel angewiesen ist, führen zeitliche Änderungen zu Fehlern im SnowFlake-Algorithmus.

Das obige ist der detaillierte Inhalt vonSo generieren Sie eine ID durch handschriftliche verteilte Schneeflocken-SnowFlake in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage