流水号生成方法——按照时间格式生成的有序唯一编码(支持并发)
2017-02-26 00:00
375 查看
这个周末挺冷的,宅在家,看完了吴军写的《硅谷之谜》,晚上忙完生活琐事之后,突然想起了最近工作时遇到了唯一编码生成的问题,突然有想法,就写了一个方法并通过了自己的测试,觉得还不错,所以分享一下。
实际工作中,我们也许会用到根据时间来生成一个有序的唯一编码作为项目编号或者流水号之类的,例如前缀+yyyyMMddHHmmss+四位有序的数字(CEO201702262330320001).为了支持并发,我加了锁,然后如果同一秒内生成的数量超过了四位数,那么做了自动等待下一秒,继续生成编码。保证了即使是多线程也是唯一,且有序。具体代码如下,有需要的朋友看参考下,当然如果有不足的地方也欢迎指正。
另外,目前这个算法是不支持分布式的,稍后,找个时间加入redis,来实现满足分布式的环境。
代码如下:
class GUniqueCode
{
private static readonly object lockTimeCode = new object();
private static Dictionary<string, int> dic = new Dictionary<string, int>();
public List<string> GSeqTimeCode(string preCode="",int pCount=1)
{
List<string> tmLs = new List<string>();
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;
}
实际工作中,我们也许会用到根据时间来生成一个有序的唯一编码作为项目编号或者流水号之类的,例如前缀+yyyyMMddHHmmss+四位有序的数字(CEO201702262330320001).为了支持并发,我加了锁,然后如果同一秒内生成的数量超过了四位数,那么做了自动等待下一秒,继续生成编码。保证了即使是多线程也是唯一,且有序。具体代码如下,有需要的朋友看参考下,当然如果有不足的地方也欢迎指正。
另外,目前这个算法是不支持分布式的,稍后,找个时间加入redis,来实现满足分布式的环境。
代码如下:
class GUniqueCode
{
private static readonly object lockTimeCode = new object();
private static Dictionary<string, int> dic = new Dictionary<string, int>();
public List<string> GSeqTimeCode(string preCode="",int pCount=1)
{
List<string> tmLs = new List<string>();
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;
}
相关文章推荐
- 高并发环境下生成订单唯一流水号方法:SnowFlake
- 两种方法利用Java生成唯一ID,取当前时间与字母随机组合,并发少的情况足以胜任
- 高并发环境下生成订单唯一流水号方法:SnowFlake
- 高并发下生成订单唯一流水号的方法
- java利用时间格式生成唯一文件名的方法
- 高并发下生成订单唯一流水号的方法
- 高并发环境下生成订单唯一流水号方法:SnowFlake
- ASP.NET 生成唯一不重复的订单号 支持多用户并发、持多数据库的实现参考(C#.NET通用权限管理系统组件源码组成部分)
- 如何在线生成Word文档?一种极简,极强大的方法,支持图片表格等各种格式
- 唯一序列号生成,自測支持高并发,不支持集群
- java时间生成格式解决方法
- 唯一序列号生成,自测支持高并发,不支持集群
- 生成时间加流水号的编码
- c#生成唯一编号方法记录,可用数据库主键 唯一+有序
- ASP+FSO生成的网页文件默认编码格式以及转换成UTF-8编码方法
- sqlSever 存储过程 中 创建 事务(增删改操作),唯一的主键自动生成 (格式:自定义字母+时间+五位数字,例如:S2014103010001)
- 高并发、分布式交易场景下唯一ID生成方法
- linux 乱码 及解决方法 locale 可以利用iconv -l 来查看linux系统都支持哪种编码格式
- 生成订单编号,编号格式(由编号类型编码+编号创建平台编码+6位日期+时间戳后4位+4位随机数组成),生成四位或者N位随机数字
- Oracle procedure递归方法生成有规律唯一不重复且连续的流水号(处理字母数字)