JAVA 雪花算法 唯一ID生成工具类
生活随笔
收集整理的這篇文章主要介紹了
JAVA 雪花算法 唯一ID生成工具类
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
package com.gblfy;/*** @Author:JCccc* @Description:* @Date: created in 15:31 2019/6/12*/
public class SnowflakeIdUtils {// ==============================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 SnowflakeIdUtils(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位的IDreturn ((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) {SnowflakeIdUtils idWorker = new SnowflakeIdUtils(3, 1);System.out.println(idWorker.nextId());}
}
總結
以上是生活随笔為你收集整理的JAVA 雪花算法 唯一ID生成工具类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VSFTPD实战02_需求
- 下一篇: vue推荐项目