这个周末挺冷的,宅在家,看完了吴军写的《硅谷之谜》,晚上忙完生活琐事之后,突然想起了最近工作时遇到了唯一编码生成的问题,突然有想法,就写了一个方法并通过了自己的测试,觉得还不错,所以分享一下。
实际工作中,我们也许会用到根据时间来生成一个有序的唯一编码作为项目编号或者流水号之类的,例如前缀+yyyyMMddHHmmss+四位有序的数字(CEO201702262330320001).为了支持并发,我加了锁,然后如果同一秒内生成的数量超过了四位数,那么做了自动等待下一秒,继续生成编码。保证了即使是多线程也是唯一,且有序。具体代码如下,有需要的朋友看参考下,当然如果有不足的地方也欢迎指正。
另外,目前这个算法是不支持分布式的,稍后,找个时间加入redis,来实现满足分布式的环境。
代码如下:
class GUniqueCode
{
private static readonly object lockTimeCode = new object();
private static Dictionary
public List
{
List
int secondCount = 1;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < pCount; i++)
{
sb.Clear();
sb.Append(preCode);
string timeCode = DateTime.Now.ToString("yyyyMMddHHmmss");
sb.Append(timeCode);
lock (lockTimeCode)
{
if (!dic.ContainsKey(timeCode))
{
if (dic.Count > 10)//定期清除内存
dic.Clear();
secondCount = 1;
dic.Add(timeCode, 1);
}
else
{
if (dic[timeCode] >= 9999)//同个时间如果生成的序号数超过9999,将等待下一秒继续生成编号
{
while(timeCode ==DateTime.Now.ToString("yyyyMMddHHmmss"))
{
Thread.Sleep(0);
}
continue;
}
dic[timeCode]++;
secondCount = dic[timeCode];
}
string strNo = secondCount.ToString().PadLeft(4, '0');
sb.Append(strNo);
tmLs.Add(sb.ToString());
}
}
return tmLs;
}