C# 使用SnowFlake算法生成分布式唯一ID(代码演示避免产生重复ID)

SnowFlake算法是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。
在多线程环境下多次调用算法中的new Snowflake.IdWorker(1, 1)会导致重复ID的出现,因此在使用该算法生成ID时,为了保证唯一性,需要使用单例模式里确保只会调用一次new Snowflake.IdWorker(1, 1)。

////单例模式  防止重复执行new Snowflake.IdWorker(1, 1)造成ID重复的问题
using System;
namespace CSharpSnowFlakeTest
{
	public sealed class SnowFlakeSingleTest
	{
		public static readonly SnowFlakeSingleTest instance = new SnowFlakeSingleTest();
		private SnowFlakeSingleTest()
		{
			worker = new Snowflake.IdWorker(1, 1);
		}
		static SnowFlakeSingleTest() { }
		public static SnowFlakeSingleTest Instance
		{
			get { return instance; }
		}
		private Snowflake.IdWorker worker;
		public string getID()
		{
			return worker.NextId().ToString();
		}
	}
}

//测试代码 用于测试多线程环境下ID是否重复
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace CSharpSnowFlakeTest
{
	class Program
	{
		//对list加锁
		static object objLock = new object();
		//存储所有SnowFlake生成的ID
		static List lString = new List();

		//定义委托 用于执行判重
		public static Action NoticeEvent;

		//查重 如果存在重复的值列出来
		static void FindRepeat()
		{
			lock (objLock)
			{
				Console.WriteLine("---------" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "----------");
				bool q = lString.GroupBy(x => x).All(x => x.Count() == 1);
				if (!q)
				{
					var test = lString.GroupBy(x => x).Where(x => x.Count() != 1).ToList();
					foreach (IGrouping key in test)
					{
						Console.WriteLine("!!!!!!!!!!!!!!!!!" + key.Key + "!!!!!!!!!!!!!!!!!");
					}
					Console.WriteLine("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
				}
				else
				{
					Console.WriteLine("---------" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + "----------");
				}
			}
		}
		//使用SnowFlake算法生成ID
		static void getsnowflakeIdTest()
		{
			for (int i = 0; i < 1000000; ++i)
			{
				string id = SnowFlakeSingleTest.Instance.getID();
				lock (objLock)
				{
					lString.Add(id);
					//每生成500000个ID进行一次判重
					if (lString.Count % 500000 == 0)
					{
						Console.WriteLine("         " + lString.Count);
						NoticeEvent();
					}
				}
			}
		}
		static void Main(string[] args)
		{
			NoticeEvent += FindRepeat;

			for (int i = 0; i < 5; i++)
			{
				Thread thread = new Thread(getsnowflakeIdTest);
				thread.Start();
			}
		}
	}
}

C#版SnowFlake Git下载地址如下:
https://github.com/ccollie/snowflake-net

上述完整代码下载地址:
https://download.csdn.net/download/coding13/11850741

你可能感兴趣的:(C#)