• 雪花算法-唯一ID生成器


    demo:

      1 public class Snowflake
      2     {
      3         private static long machineId;//机器ID
      4         private static long datacenterId = 0L;//数据ID
      5         private static long sequence = 0L;//计数从零开始
      6 
      7         private static readonly long twepoch = 806083200000L; //唯一时间随机量
      8 
      9         private static readonly long machineIdBits = 5L; //机器码字节数
     10         private static readonly long datacenterIdBits = 5L;//数据字节数
     11         public static long maxMachineId = -1L ^ (-1L << (int)machineIdBits); //最大机器ID
     12         private static readonly long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);//最大数据ID
     13 
     14         private static readonly long sequenceBits = 12L; //计数器字节数,12个字节用来保存计数码        
     15         private static readonly long machineIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
     16         private static readonly long datacenterIdShift = sequenceBits + machineIdBits;
     17         private static readonly long timestampLeftShift = sequenceBits + machineIdBits + datacenterIdBits; //时间戳左移动位数就是机器码+计数器总字节数+数据字节数
     18         public static long sequenceMask = -1L ^ (-1L << (int)sequenceBits); //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
     19         private static long lastTimestamp = -1L;//最后时间戳
     20 
     21         private static object syncRoot = new object();//加锁对象
     22         static Snowflake snowflake;
     23 
     24         public static Snowflake Instance()
     25         {
     26             if (snowflake == null)
     27                 snowflake = new Snowflake();
     28             return snowflake;
     29         }
     30 
     31         public Snowflake()
     32         {
     33             Snowflakes(0L, 0L);
     34         }
     35 
     36         public Snowflake(long machineId)
     37         {
     38             Snowflakes(machineId, -1);
     39         }
     40 
     41         public Snowflake(long machineId, long datacenterId)
     42         {
     43             Snowflakes(machineId, datacenterId);
     44         }
     45 
     46         private void Snowflakes(long machineId, long datacenterId)
     47         {
     48             if (machineId >= 0)
     49             {
     50                 if (machineId > maxMachineId)
     51                 {
     52                     throw new Exception("机器码ID非法");
     53                 }
     54                 Snowflake.machineId = machineId;
     55             }
     56             if (datacenterId >= 0)
     57             {
     58                 if (datacenterId > maxDatacenterId)
     59                 {
     60                     throw new Exception("数据中心ID非法");
     61                 }
     62                 Snowflake.datacenterId = datacenterId;
     63             }
     64         }
     65 
     66         /// <summary>
     67         /// 生成当前时间戳
     68         /// </summary>
     69         /// <returns>毫秒</returns>
     70         private static long GetTimestamp()
     71         {
     72             return (long)(DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalMilliseconds;
     73         }
     74 
     75         /// <summary>
     76         /// 获取下一微秒时间戳
     77         /// </summary>
     78         /// <param name="lastTimestamp"></param>
     79         /// <returns></returns>
     80         private static long GetNextTimestamp(long lastTimestamp)
     81         {
     82             long timestamp = GetTimestamp();
     83             if (timestamp <= lastTimestamp)
     84             {
     85                 timestamp = GetTimestamp();
     86             }
     87             return timestamp;
     88         }
     89 
     90         /// <summary>
     91         /// 获取长整形的ID
     92         /// </summary>
     93         /// <returns></returns>
     94         public long GetId()
     95         {
     96             lock (syncRoot)
     97             {
     98                 long timestamp = GetTimestamp();
     99                 if (lastTimestamp == timestamp)
    100                 { //同一微妙中生成ID
    101                     sequence = (sequence + 1) & sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
    102                     if (sequence == 0)
    103                     {
    104                         //一微妙内产生的ID计数已达上限,等待下一微妙
    105                         timestamp = GetNextTimestamp(lastTimestamp);
    106                     }
    107                 }
    108                 else
    109                 {
    110                     //不同微秒生成ID
    111                     sequence = 0L;
    112                 }
    113                 if (timestamp < lastTimestamp)
    114                 {
    115                     throw new Exception("时间戳比上一次生成ID时时间戳还小,故异常");
    116                 }
    117                 lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
    118                 long Id = ((timestamp - twepoch) << (int)timestampLeftShift)
    119                     | (datacenterId << (int)datacenterIdShift)
    120                     | (machineId << (int)machineIdShift)
    121                     | sequence;
    122                 return Id;
    123             }
    124         }
    125     }
  • 相关阅读:
    docker构建本地仓库后,无法登陆解决办法(CentOS/Ubuntu)
    Python3.0以上版本在对比图片相似中的应用
    合并dict、list的方法
    虚拟机Centos安装配置
    冒泡排序和鸡尾酒排序(code)
    自定义 Django admin 组件
    Django 之 modelForm (edit.html页面的编写)
    模型 _meta API ( options )
    Django orm Q查询补充
    Django:locals()小技巧
  • 原文地址:https://www.cnblogs.com/zhangzhang1118/p/13491468.html
Copyright © 2020-2023  润新知