每天生成唯一的6位数字
本文关键字:6位 数字 唯一 每天 | 更新日期: 2023-09-27 18:06:09
我正在开发一个多进程解决方案,必须为一些对象分配6位唯一数字(指定超过6位数字或使用字母数字字符是不可能的)。这个数字的长度是第三方约束)。
因为这是一个多进程解决方案(我的应用程序的多个实例将同时运行),我不能依赖于在我的项目中使用锁与共享变量,我想防止使用共享存储(db/文件系统/…)来维护和生成这些唯一的数字。
而且,我不太可能每天需要超过30万个唯一的数字。
是否有一种算法(可能取决于一天中的时间)可以每天生成唯一的6位数?
是否有可能将数字分组给每个线程?Ie。如果您总共有30万个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个,然后完成)。
关于给出的所有评论和信息,似乎解决方案在于每个线程可以有一个3位数的唯一id。然后您可以为每个线程分配1000个唯一id,这就足够了。既然你这么说:
- "是的,分布几乎是平衡的"
- "我不太可能每天需要超过30万个唯一的数字"
- "大约100-300个进程"
每个线程需要超过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
以检查线程是否可以接受新作业