【问题标题】:generate random string so no two threads collide生成随机字符串,因此没有两个线程发生冲突
【发布时间】:2015-06-27 18:22:04
【问题描述】:

这是我的随机字符串生成器的代码

private static string GetUniqueKey()
{
    int maxSize  = 15 ;
    char[] chars = new char[62];
    string a = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
    chars = a.ToCharArray();
    int size  = maxSize ;
    byte[] data = new byte[1];
    RNGCryptoServiceProvider  crypto = new RNGCryptoServiceProvider();
    crypto.GetNonZeroBytes(data) ;
    size =  maxSize ;
    data = new byte[size];
    crypto.GetNonZeroBytes(data);
    StringBuilder result = new StringBuilder(size) ;
    foreach(byte b in data )
    {
        result.Append(chars[b % (chars.Length - 1)]);
    }
    return result.ToString();

}

如何编写一个单元测试来测试 100% 保证没有 2 个线程会生成相同的随机数

我不想锁定线程,因为它会在极端负载测试下造成性能噩梦。

此逻辑将用于负载平衡的 8 个应用服务器。

我不能使用 GUID,因为这个随机字符串应该像信用卡号一样可读。

在存储到数据库之前,我是否必须不断读取数据库以确保这是一个唯一编号?

【问题讨论】:

  • Guid.NewGuid 怎么样?
  • 当使用没有单例的随机化器或控制随机化器的锁线程时,您不能:随机的定义是您从定义的(但非常大的)集合中获取随机值。您只能通过使您从中生成随机值的基集足够大来影响不获得相同随机值的机会。
  • 即使是大集合,我如何确保这在 DB 中是唯一的?
  • 您说“我不能使用 GUID,因为这个随机字符串应该像信用卡号一样可读”,因此您可以处理 GUID 上的校验和并提供其十六进制编码。或者,为什么不将服务器唯一 ID 与每个服务器设置的增量编号连接起来?
  • 旁注:您要保证每 2 个随机数都是唯一的,这一事实保证这些是非随机数。

标签: c# asp.net multithreading random uniqueidentifier


【解决方案1】:
  1. 它与线程有什么关系?
  2. 我只是想确保这个数字是唯一的,这样它就不会在数据库中存储两次。

有不同的方法来做到这一点:

一个。将数据库中的所有键加载到列表中,然后查询列表 我不是很喜欢这种方式,但如果它是一个小列表,最好每次都查询数据库。

b.每次从数据库读取,取决于数据库是否是本地的。

c。具有内部机制,将根据保存在 DB 中的最后一个生成新的唯一键。例如,如果最后保存的密钥是 AAA,那么您知道下一个将是 AAB。只是一个想法

d。将此唯一键定义为主键,如果您尝试添加相同的键,您将收到异常 --> 尝试 catch 可能会有所帮助。 我不太喜欢它,因为它也会影响性能。

我正在学习 b 或 c。 也许还有其他解决方案,根据需求/需要尝试看看哪种更适合您。

【讨论】:

    【解决方案2】:

    你有 n 个工作线程。您应该有一组共享的字符串和一个中心线程来处理该组。生命周期应该是这样的:

    1. 工作线程生成字符串。如果它已经存在于队列中,则重复此步骤,直到得到一个新字符串。

    2. 当您有一个新字符串不存在于集合中时,工作线程应将其作为候选添加到集合中。

    3. 您的中心线程应该检查候选者。如果给定的候选人在集合中重复,则将它们标记为重复。如果它们不是集合中的重复项,则根据数据库检查它们。如果是重复的,则将其标记为重复。如果没有,则将其标记为成功。通知这些值背后的工作线程。

    4. 通知的工作线程应将该值标记为已确认,如果该值重复,则跳转到步骤 1。

    5. 中心线程应处理已确认的元素并将其从集合中移除。

    最好在中心线程中缓存一些元素,以减少在值重复时需要处理数据库的可能性。

    【讨论】:

      【解决方案3】:

      为什么和线程有关?

      我的意思是,如果您可能在 2 个不同的线程中获得相同的数字,那么您也可能在非并行场景中获得它。 获得相同的数字与线程无关。 顺便说一句,您可以使用 Guid.NewGuid() 来获取唯一键。

      【讨论】:

      • 这个随机字符串应该是人类可读的,所以我不能使用 GUID
      • 我只是想确保这个数字是唯一的,这样它就不会在数据库中存储两次。
      猜你喜欢
      • 2019-05-21
      • 2011-03-19
      • 1970-01-01
      • 2017-08-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多