日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

雪花算法生成数字id_全局唯一iD的生成 雪花算法详解及其他用法

發布時間:2025/3/15 编程问答 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 雪花算法生成数字id_全局唯一iD的生成 雪花算法详解及其他用法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

SnowflakeIdWorker {

// ==============================Fields===========================================

/**

* 開始時間截 (2015-01-01)

*/

private final long twepoch = 1420041600000L;

/**

* 機器id所占的位數

*/

private final long workerIdBits = 5L;

/**

* 數據標識id所占的位數

*/

private final long datacenterIdBits = 5L;

/**

* 支持的最大機器id,結果是31 (這個移位算法可以很快的計算出幾位二進制數所能表示的最大十進制數)

*/

private final long maxWorkerId = -1L ^ (-1L << workerIdBits);

/**

* 支持的最大數據標識id,結果是31

*/

private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);

/**

* 序列在id中占的位數

*/

private final long sequenceBits = 12L;

/**

* 機器ID向左移12位

*/

private final long workerIdShift = sequenceBits;

/**

* 數據標識id向左移17位(12+5)

*/

private final long datacenterIdShift = sequenceBits + workerIdBits;

/**

* 時間截向左移22位(5+5+12)

*/

private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;

/**

* 生成序列的掩碼,這里為4095 (0b111111111111=0xfff=4095)

*/

private final long sequenceMask = -1L ^ (-1L << sequenceBits);

/**

* 工作機器ID(0~31)

*/

private long workerId;

/**

* 數據中心ID(0~31)

*/

private long datacenterId;

/**

* 毫秒內序列(0~4095)

*/

private long sequence = 0L;

/**

* 上次生成ID的時間截

*/

private long lastTimestamp = -1L;

//==============================Constructors=====================================

/**

* 構造函數

*

* @param workerId 工作ID (0~31)

* @param datacenterId 數據中心ID (0~31)

*/

public SnowflakeIdWorker(long workerId, long datacenterId) {

if (workerId > maxWorkerId || workerId < 0) {

throw new IllegalArgumentException(String.format("worker Id can't be greater than %d or less than 0", maxWorkerId));

}

if (datacenterId > maxDatacenterId || datacenterId < 0) {

throw new IllegalArgumentException(String.format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));

}

this.workerId = workerId;

this.datacenterId = datacenterId;

}

// ==============================Methods==========================================

/**

* 獲得下一個ID (該方法是線程安全的)

*

* @return SnowflakeId

*/

public synchronized long nextId() {

long timestamp = timeGen();

//如果當前時間小于上一次ID生成的時間戳,說明系統時鐘回退過這個時候應當拋出異常

if (timestamp < lastTimestamp) {

throw new RuntimeException(

String.format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));

}

//如果是同一時間生成的,則進行毫秒內序列

if (lastTimestamp == timestamp) {

sequence = (sequence + 1) & sequenceMask;

//毫秒內序列溢出

if (sequence == 0) {

//阻塞到下一個毫秒,獲得新的時間戳

timestamp = tilNextMillis(lastTimestamp);

}

}

//時間戳改變,毫秒內序列重置

else {

sequence = 0L;

}

//上次生成ID的時間截

lastTimestamp = timestamp;

//移位并通過或運算拼到一起組成64位的ID

return ((timestamp - twepoch) << timestampLeftShift) //

| (datacenterId << datacenterIdShift) // | (workerId << workerIdShift) // |sequence;

}

/**

* 阻塞到下一個毫秒,直到獲得新的時間戳

*

* @param lastTimestamp 上次生成ID的時間截

* @return 當前時間戳

*/

protected long tilNextMillis(long lastTimestamp) {

long timestamp = timeGen();

while (timestamp <= lastTimestamp) {

timestamp = timeGen();

}

return timestamp;

}

/**

* 返回以毫秒為單位的當前時間

*

* @return 當前時間(毫秒)

*/

protected long timeGen() {

return System.currentTimeMillis();

}

//==============================Test=============================================

/**

* 測試

*/

public static void main(String[] args) {

long start = System.currentTimeMillis();

SnowflakeIdWorker idWorker = new SnowflakeIdWorker(1, 3);

for (int i = 0; i < 50; i++) {

long id = idWorker.nextId();

System.out.println(Long.toBinaryString(id));

System.out.println(id);

}

long end = System.currentTimeMillis();

System.out.println(end - start);

}

}

總結

以上是生活随笔為你收集整理的雪花算法生成数字id_全局唯一iD的生成 雪花算法详解及其他用法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。