C# 实现 Snowflake算法生成唯一性Id
参考地址:https://blog.csdn.net/w200221626/article/details/52064976
/// <summary>
/// 动态生产有规律的ID
/// </summary>
public class Snowflake
{
private static long machineId;//机器ID
private static long datacenterId = 0L;//数据ID
private static long sequence = 0L;//计数从零开始 private static long twepoch = 687888001020L; //唯一时间随机量 private static long machineIdBits = 5L; //机器码字节数
private static long datacenterIdBits = 5L;//数据字节数
public static long maxMachineId = -1L ^ -1L << (int)machineIdBits; //最大机器ID
private static long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);//最大数据ID private static long sequenceBits = 12L; //计数器字节数,12个字节用来保存计数码
private static long machineIdShift = sequenceBits; //机器码数据左移位数,就是后面计数器占用的位数
private static long datacenterIdShift = sequenceBits + machineIdBits;
private static long timestampLeftShift = sequenceBits + machineIdBits + datacenterIdBits; //时间戳左移动位数就是机器码+计数器总字节数+数据字节数
public static long sequenceMask = -1L ^ -1L << (int)sequenceBits; //一微秒内可以产生计数,如果达到该值则等到下一微妙在进行生成
private static long lastTimestamp = -1L;//最后时间戳 private static object syncRoot = new object();//加锁对象
static Snowflake snowflake; public static Snowflake Instance()
{
if (snowflake == null)
snowflake = new Snowflake();
return snowflake;
} public Snowflake()
{
Snowflakes(0L, -);
} public Snowflake(long machineId)
{
Snowflakes(machineId, -);
} public Snowflake(long machineId, long datacenterId)
{
Snowflakes(machineId, datacenterId);
} private void Snowflakes(long machineId, long datacenterId)
{
if (machineId >= )
{
if (machineId > maxMachineId)
{
throw new Exception("机器码ID非法");
}
Snowflake.machineId = machineId;
}
if (datacenterId >= )
{
if (datacenterId > maxDatacenterId)
{
throw new Exception("数据中心ID非法");
}
Snowflake.datacenterId = datacenterId;
}
} /// <summary>
/// 生成当前时间戳
/// </summary>
/// <returns>毫秒</returns>
private static long GetTimestamp()
{
return (long)(DateTime.UtcNow - new DateTime(, , , , , , DateTimeKind.Utc)).TotalMilliseconds;
} /// <summary>
/// 获取下一微秒时间戳
/// </summary>
/// <param name="lastTimestamp"></param>
/// <returns></returns>
private static long GetNextTimestamp(long lastTimestamp)
{
long timestamp = GetTimestamp();
if (timestamp <= lastTimestamp)
{
timestamp = GetTimestamp();
}
return timestamp;
} /// <summary>
/// 获取长整形的ID
/// </summary>
/// <returns></returns>
public long GetId()
{
lock (syncRoot)
{
long timestamp = GetTimestamp();
if (Snowflake.lastTimestamp == timestamp)
{ //同一微妙中生成ID
sequence = (sequence + ) & sequenceMask; //用&运算计算该微秒内产生的计数是否已经到达上限
if (sequence == )
{
//一微妙内产生的ID计数已达上限,等待下一微妙
timestamp = GetNextTimestamp(Snowflake.lastTimestamp);
}
}
else
{
//不同微秒生成ID
sequence = 0L;
}
if (timestamp < lastTimestamp)
{
throw new Exception("时间戳比上一次生成ID时时间戳还小,故异常");
}
Snowflake.lastTimestamp = timestamp; //把当前时间戳保存为最后生成ID的时间戳
long Id = ((timestamp - twepoch) << (int)timestampLeftShift)
| (datacenterId << (int)datacenterIdShift)
| (machineId << (int)machineIdShift)
| sequence;
return Id;
} }
}
测试代码:
class Program
{
static void Main(string[] args)
{
var blockingCollection = new BlockingCollection<long>();
List<Task> tasks = new List<Task>();
for (int i = ; i < ; i++)
{
var task = Task.Run(() =>
{ for (int j = ; j < ; j++)
{ //blockingCollection.Add(Snowflake.Instance().GetId());//一台机器 blockingCollection.Add(new Snowflake(,).GetId());//多台机器
}
}); tasks.Add(task);
} Task.WaitAll(tasks.ToArray()); Console.WriteLine(blockingCollection.Distinct().Count()); Console.ReadKey(); }
}
github:https://github.com/RobThree/IdGen
C# 实现 Snowflake算法生成唯一性Id的更多相关文章
- 根据twitter的snowflake算法生成唯一ID
C#版本 /// <summary> /// 根据twitter的snowflake算法生成唯一ID /// snowflake算法 64 位 /// 0---0000000000 000 ...
- C# 根据twitter的snowflake算法生成唯一ID
C# 版算法: using System; using System.Collections.Generic; using System.Linq; using System.Text; using ...
- PHP使用SnowFlake算法生成唯一ID
前言:最近需要做一套CMS系统,由于功能比较单一,而且要求灵活,所以放弃了WP这样的成熟系统,自己做一套相对简单一点的.文章的详情页URL想要做成url伪静态的格式即xxx.html 其中xxx考虑过 ...
- 关于snowflake算法生成的ID转换为JS的数字类型由于过大导致JS精度丢失的问题
JS的数字类型目前支持的最大值为:9007199254740992,一旦数字超过这个值,JS将会丢失精度,导致前后端的值出现不一致. JAVA的Long类型的 最大值为:922337203 ...
- 使用SnowFlake算法生成唯一ID
转自:https://segmentfault.com/a/1190000007769660 考虑过的方法有 直接用时间戳,或者以此衍生的一系列方法 Mysql自带的uuid 以上两种方法都可以查到就 ...
- 封装各种生成唯一性ID算法的工具类
/** * Copyright (c) 2005-2012 springside.org.cn * * Licensed under the Apache License, Version 2.0 ( ...
- 基于雪花算法生成分布式ID(Java版)
SnowFlake算法原理介绍 在分布式系统中会将一个业务的系统部署到多台服务器上,用户随机访问其中一台,而之所以引入分布式系统就是为了让整个系统能够承载更大的访问量.诸如订单号这些我们需要它是全局唯 ...
- 雪花算法生成分布式ID
分布式主键ID生成方案 分布式主键ID的生成方案有以下几种: 数据库自增主键 缺点: 导入旧数据时,可能会ID重复,导致导入失败 分布式架构,多个Mysql实例可能会导致ID重复 UUID 缺点: 占 ...
- Java 利用 UUID 生成唯一性 ID 示例代码
用户ID首先生成,订单ID的生成可依赖用户ID. 下面代码前六位是日期,后八位是随机数,用于生成用户ID. public String getNewUserId() { String ipAddres ...
随机推荐
- GetFontResourceInfo 函数: 获取字体文件对应的字体名
在 win 7, gdi32.dll,找不到 GetFontResourceInfo(), 但能找到 GetFontResourceInfoW(), 用法类似. //----------------- ...
- java eclipse中使用wsdl生成soap 的客户端代码
项目右键--> new --> other finish完成
- postman接口测试笔记
1.GET 和POST 的区别: GET 使用URL 或Cookie 传参,而POST将数据放在Body 中. GET的URL 在长度上会有限制,而POST没有. POST比GET相对安全,因为在地址 ...
- VMware 安装虚拟机系统
Ø 简介 本文主要介绍使用 VMware 安装虚拟机系统. 1. 创建虚拟机 1) 打开VMware,创建新虚拟机 2) 选择需要安装系统的iso镜像文件 3) 选择需要安装的Win ...
- win-DOS命令整理
1 md 建 文件夹2 cd 指向文件夹方向cd .. 进入上一级文件夹cd \ 回到根目录3 rd 删除文件夹4 dir 查看文件夹里的文件 dir /a 查看文件夹内全部文件含隐藏文件 5 ren ...
- Vue插槽的深入理解和应用
一开始接触vue时并不知道插槽是什么,后来看了很多文章也是一知半解.然后自己手动敲了一下,在项目中实际应用一下,实在太好用了.后来做小程序后发现也能使用slot,不单单在vue中使用.我就是这么目光短 ...
- CPU或以太网模块重启DHCP请求
最近,带了一个实习生,一天: 他:师傅,PLC如何首次分配IP地址啊? 我:不是教过你了吗? 他:我怎么用BOOTP软件,半天没有反应啊? 我:..... 原来,他做实验的CPU已经被分配IP地址了, ...
- css-reset 代码
最常用 * { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } *:bef ...
- java 中final关键字
1.final变量,一旦该变量被设定,就不可以再改变该变量的值. final关键字定义的变量必须声明时赋值.一旦一个对象引用被修饰为final后,它只能恒定指向一个对象,一个既是static和fina ...
- react项目构建
1.react脚手架 npm install -g create-react-app create-react-app myproject 2.页面配置(bootcdn) <script src ...