最近看了twitter的分布式自增ID算法Snowflak,自己根据开源的代码写了一个c#的版本,以记录学习。twitter的开源项目地址为:https://github.com/twitter/snowflake用Scala实现
类IdWorker {//机器标识位数 私人const int WORKER_ID_BITS=4;//机器标识位的最大值 私人const长MAX_WORKER_ID=1 l ^ 1 l & lt; & lt;WORKER_ID_BITS;//毫秒内自增位 私人const int SEQUENCE_BITS=10;//自增位最大值 私人const长SEQUENCE_Mask=1 l ^ 1 l & lt; & lt;SEQUENCE_BITS; 私人const长twepoch=1398049504651 l;//时间毫秒值向左偏移位 私人const int timestampLeftShift=SEQUENCE_BITS + WORKER_ID_BITS;//机器标识位向左偏移位 私人const int WORKER_ID_SHIFT=SEQUENCE_BITS; 私有静态只读的DateTime START_TIME=新系统。DateTime(1970年1 1 0,0,0,0); 私有静态只读的对象锁=新对象(); 私人长=0 l序列; 私人长lastTimestamp=1 l; 私人长workerId; 公共IdWorker(长workerId) { 如果(workerId比;MAX_WORKER_ID | | workerId & lt;0) { 把新的ArgumentException(字符串。格式(“工人id不能大于{0}或小于0”,MAX_WORKER_ID)); } 这一点。workerId=workerId; }///& lt; summary>///获取下一个id值///& lt;/summary>///& lt; returns> & lt;/returns> 公共长NextId () { 锁(锁) { 长时间戳=TimeGen ();//当前时间小于上一次时间,错误 如果(时间戳& lt;this.lastTimestamp) { 抛出新的异常(字符串。格式(“时钟倒退。拒绝为% d毫秒”生成id, lastTimestamp -时间戳)); }//当前毫秒内 如果这一点。lastTimestamp==时间戳) {//+ 1求余 这一点。=(这个序列。序列+ 1),SEQUENCE_Mask;//当前毫秒内计数满了,等待下一秒 如果这一点。序列==0) { 时间戳=tilNextMillis (lastTimestamp); } }//其他不是当前毫秒内 { 这一点。序列=0;//重置当前毫秒计数 } 这一点。lastTimestamp=时间戳;//当前毫秒值|机器标识值|当前毫秒内自增值 长nextId=((时间戳- twepoch & lt; & lt;timestampLeftShift)) |(这一点。workerId & lt; & lt;WORKER_ID_SHIFT) | (this.sequence); 返回nextId; } }///& lt; summary>///等待下一个毫秒///& lt;/summary>///& lt;参数name=" lastTimestamp祝辞& lt;/param>///& lt; returns> & lt;/returns> 私人长tilNextMillis(长lastTimestamp) { 长时间戳=TimeGen (); 而(时间戳& lt;=lastTimestamp) { 时间戳=TimeGen (); } 返回时间戳; }///& lt; summary>///获取当前时间的Unix时间戳///& lt;/summary>///& lt; returns> & lt;/returns> 私人长TimeGen () { (DateTime.UtcNow返回。蜱虫- START_TIME.Ticks)/10000; } }
调用方式如下
静态void Main (string [] args) { IdWorker工人=new IdWorker l (12); for (int i=0;我& lt;100000;我+ +) { Console.WriteLine (worker.NextId ()); } }