Das Ergebnis der vom SnowFlake-Algorithmus generierten ID ist eine 64-Bit-Ganzzahl. Seine Struktur ist wie folgt:
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()); } }
Die Methode zum Erhalten der ID im Code wird mithilfe von Bitoperationen implementiert
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:
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!