每天生成唯一的6位数字

本文关键字:6位 数字 唯一 每天 | 更新日期: 2023-09-27 18:06:09

我正在开发一个多进程解决方案,必须为一些对象分配6位唯一数字(指定超过6位数字或使用字母数字字符是不可能的)。这个数字的长度是第三方约束)。

因为这是一个多进程解决方案(我的应用程序的多个实例将同时运行),我不能依赖于在我的项目中使用锁与共享变量,我想防止使用共享存储(db/文件系统/…)来维护和生成这些唯一的数字。

而且,我不太可能每天需要超过30万个唯一的数字。
是否有一种算法(可能取决于一天中的时间)可以每天生成唯一的6位数?

每天生成唯一的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以检查线程是否可以接受新作业