根据twitter的snowflake算法生成唯一ID
生活随笔
收集整理的這篇文章主要介紹了
根据twitter的snowflake算法生成唯一ID
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
C#版本
/// <summary>/// 根據twitter的snowflake算法生成唯一ID/// snowflake算法 64 位/// 0---0000000000 0000000000 0000000000 0000000000 0 --- 00000 ---00000 ---000000000000/// 第一位為未使用(實際上也可作為long的符號位),接下來的41位為毫秒級時間,然后5位datacenter標識位,5位機器ID(并不算標識符,實際是為線程標識),然后12位該毫秒內的當前毫秒內的計數,加起來剛好64位,為一個Long型。/// 其中datacenter標識位起始是機器位,機器ID其實是線程標識,可以同一一個10位來表示不同機器/// </summary>public class IdWorker{//機器IDprivate static long workerId = 1;private static long twepoch = 687888001020L; //唯一時間,這是一個避免重復的隨機量,自行設定不要大于當前時間戳private static long sequence = 0L;private static int workerIdBits = 4; //機器碼字節數。4個字節用來保存機器碼public static long maxWorkerId = -1L ^ -1L << workerIdBits; //最大機器IDprivate static int sequenceBits = 10; //計數器字節數,10個字節用來保存計數碼private static int workerIdShift = sequenceBits; //機器碼數據左移位數,就是后面計數器占用的位數private static int timestampLeftShift = sequenceBits + workerIdBits; //時間戳左移動位數就是機器碼和計數器總字節數public static long sequenceMask = -1L ^ -1L << sequenceBits; //一微秒內可以產生計數,如果達到該值則等到下一微妙在進行生成private long lastTimestamp = -1L;public long nextId(){lock (this){long timestamp = timeGen();if (this.lastTimestamp == timestamp){ //同一微妙中生成IDIdWorker.sequence = (IdWorker.sequence + 1) & IdWorker.sequenceMask; //用&運算計算該微秒內產生的計數是否已經到達上限if (IdWorker.sequence == 0){//一微妙內產生的ID計數已達上限,等待下一微妙timestamp = tillNextMillis(this.lastTimestamp);}}else{ //不同微秒生成IDIdWorker.sequence = 0; //計數清0}if (timestamp < lastTimestamp){ //如果當前時間戳比上一次生成ID時時間戳還小,拋出異常,因為不能保證現在生成的ID之前沒有生成過throw new Exception(string.Format("Clock moved backwards. Refusing to generate id for {0} milliseconds",this.lastTimestamp - timestamp));}this.lastTimestamp = timestamp; //把當前時間戳保存為最后生成ID的時間戳long nextId = (timestamp - twepoch << timestampLeftShift) | IdWorker.workerId << IdWorker.workerIdShift | IdWorker.sequence;return nextId;}}/// <summary>/// 獲取下一微秒時間戳/// </summary>/// <param name="lastTimestamp"></param>/// <returns></returns>private long tillNextMillis(long lastTimestamp){long timestamp = timeGen();while (timestamp <= lastTimestamp){timestamp = timeGen();}return timestamp;}/// <summary>/// 生成當前時間戳/// </summary>/// <returns></returns>private long timeGen(){return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;}}JAVA版本
import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component;public class IdWorker {protected static final Logger LOG = LoggerFactory.getLogger(IdWorker.class);private long workerId;private long datacenterId;private long sequence = 0L;private long twepoch = 1288834974657L;private long workerIdBits = 5L;private long datacenterIdBits = 5L;private long maxWorkerId = -1L ^ (-1L << workerIdBits);private long maxDatacenterId = -1L ^ (-1L << datacenterIdBits);private long sequenceBits = 12L;private long workerIdShift = sequenceBits;private long datacenterIdShift = sequenceBits + workerIdBits;private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;private long sequenceMask = -1L ^ (-1L << sequenceBits);private long lastTimestamp = -1L;public IdWorker(long workerId, long datacenterId) {// sanity check for workerIdif (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;LOG.info(String.format("worker starting. timestamp left shift %d, datacenter id bits %d, worker id bits %d, sequence bits %d, workerid %d", timestampLeftShift, datacenterIdBits, workerIdBits, sequenceBits, workerId));}public synchronized long nextId() {long timestamp = timeGen();if (timestamp < lastTimestamp) {LOG.error(String.format("clock is moving backwards. Rejecting requests until %d.", 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;}lastTimestamp = timestamp;return ((timestamp - twepoch) << timestampLeftShift) | (datacenterId << datacenterIdShift) | (workerId << workerIdShift) | sequence;}protected long tilNextMillis(long lastTimestamp) {long timestamp = timeGen();while (timestamp <= lastTimestamp) {timestamp = timeGen();}return timestamp;}protected long timeGen() {return System.currentTimeMillis();}}總結
以上是生活随笔為你收集整理的根据twitter的snowflake算法生成唯一ID的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 头部ct解剖图(头部ct)
- 下一篇: js判断只能输入数字或小数点