我正在开发一个多进程解决方案,并且必须为某些对象分配6位数的唯一数字(指定超过6位数或使用字母数字字符是不可能的。此数字的长度是第三方约束)。
因为这是一个多进程解决方案(我的应用程序的多个实例将同时运行),所以我不能依赖于在项目中使用锁定共享变量,而且我想阻止使用共享存储(db / file system / ...)来维护和生成这些唯一的数字。
另外,我每天需要超过300,000个唯一号码的可能性很小 是否有一种算法(可能取决于一天中的时间),每天可以生成唯一的6位数字?
答案 0 :(得分:4)
是否可以将每组数字分成几个? IE浏览器。如果你有总共300 000个id号和3个线程,那么你可以为每个线程提供一个工作间隔。
Thread 1 -> 1 - 99 9999
Thread 2 -> 100 000 - 199 999
Thread 3 -> 200 000 - 300 000
您也可以提供较小的间隔,并为线程分配一些可以使用的ID,当它用完时,它必须返回并向中央ID组织者请求一组新的ID。
会像
while(HasWorkTodo)
{
foreach(int uniqueId in GetUniqueIDIntervalFromCentralIdController()) // get 10000 ids at a time
{
//work with globally unique id
}
}
如果id的数量不是太多,我也会用一些方法将未使用的ID交还给主id控制器(即如果你的线程请求1000个ID但只使用50然后完成)。
答案 1 :(得分:2)
关于所有给出的评论和信息,似乎解决方案在于每个线程可以具有3位唯一ID。然后你可以为每个线程分配1000个唯一的id就足够了。既然你准备好了:
每个线程需要超过300个id,“极不可能”。让它成为1000(“我们可以!”)。
然后,在给定的线程中,使用以下类的单个实例来生成ID。不需要它static
,只需给定线程的整个批次的相同实例
public class ThreadUniqueIdProvider
{
private int ThreadId { get; set; }
private int IdIndex { get; set; }
public ThreadUniqueIdProvider(int threadId)
{
if (threadId < 0 || threadId > 999)
throw new ArgumentException("Thread unique identifier must be in [0, 999]");
this.ThreadId = threadId;
}
public bool HasReachedLimit
{
get
{
return this.IdIndex >= 999;
}
}
public int NextId
{
get
{
if (this.HasReachedLimit)
throw new Exception("Impossible to allocate more than 1000 Unique Ids per thread");
this.IdIndex++;
return this.ThreadId * 1000 + this.IdIndex;
}
}
}
只需在需要时拨打NextId
。
修改强>
根据评论,添加HasReachedLimit
以检查线程是否可以接受新作业。