【问题标题】:Concurrent random number generation in JavaJava中的并发随机数生成
【发布时间】:2016-01-02 15:11:54
【问题描述】:

在 Web 服务器上,许多线程将内容提供给客户端。 A/B 测试在网站上执行,因此我们需要一个 PRNG 来为每个会话和测试选择一个变体。 显然,当使用 PRNG 的单个实例时,它是同时访问的,因此可能需要适当的锁定或其他机制。

最初我们使用java.util.Random(juR),但由于它有提到的缺陷,例如How good is java.util.Random,我们尝试改用 MersenneTwister。 然而,由于 Mersenne-Twister relies on an internal state,我们看到性能大幅下降,因此它对 nextInt() 的访问需要同步。 另一种方法可能是异或移位 PRNG,但它与 Mersenne Twister 存在相同的问题。 您可以找到解释,例如这里:http://xorshift.di.unimi.it/

Randomuses a compareAndSet 操作,这似乎要快得多,因为它不需要锁定,但根据 Javadoc 类,它仍然不是线程安全的。相反,建议改用ThreadLocalRandom,这基本上会导致PRNG池。根据请求,随机可用线程处理 HTTPS 请求,因此从一组可用 PRNG 中选择一个随机 PRNG。显然这是相当快的。

从这样的池中生成的随机数是否与从单个 PRNG 实例中生成的随机数一样好?

另一种方法是使用单个 PRNG 实例从中预生成值流,例如通过使用ArrayBlockingQueue

哪种解决方案在性能方面会更好?

【问题讨论】:

  • 对于这个应用程序(选择是否向用户显示 A 或 B)随机数的质量并不重要,只要它们是均匀分布的。
  • 您正在努力进行预优化。 Random 被记录为线程安全的,与 Web 应用程序所需的所有 IO(数据库查询、HTTP 请求等)相比,每次启动会话时调用 nextBoolean() 在性能方面完全可以忽略不计。
  • 这个想法试图在随机数质量方面提出比 java.util.Random 更好的东西。我们实际上有不止两个变体,所以我们绘制整数。 @Henry 据我所知,Random 中位的概率分布不均。
  • 即便如此,Random 已经足够好了。但是如果你想要一个完美的分布,你甚至不需要一个 Random 。只需使用 AtomicInteger 并在每次会话开始时递增它。然后计算变体数量的模数。您所需要的只是良好的分布,而不是良好的随机性。
  • 我的问题仍然没有答案。 PRNG 池是否与单个 PRNG 一样好?

标签: java multithreading random


【解决方案1】:

您可以通过BlockingQueue 传递结果来使任何随机数生成器线程安全。

class SafeRandom implements Runnable {

    Random r = new Random();
    BlockingQueue<Double> q = new ArrayBlockingQueue<>(10);

    double get() throws InterruptedException {
        return q.take();
    }

    @Override
    public void run() {
        try {
            while (true) {
                q.put(r.nextDouble());
            }
        } catch (InterruptedException ie) {
        }
    }

}

【讨论】:

    【解决方案2】:

    为避免同步问题,每个线程都有一个 RNG。为避免特定于线程的 RNG 给出相同的输出,请让主 RNG 为特定于线程的 RNG 生成一系列初始种子。这可能需要将额外的种子参数传递到您的代码中以生成新线程。

    您需要亲自测试 RNG 的不同选项在您的套件上运行的速度。如果需要,可以为主 RNG 和线程特定的 RNG 使用不同的 RNG 引擎。通常为线程特定的 RNG 选择具有快速设置时间的 RNG。这对于主 RNG 来说并不重要,因为它只设置一次。

    【讨论】:

      猜你喜欢
      • 2015-11-25
      • 1970-01-01
      • 1970-01-01
      • 2012-04-28
      • 2011-03-19
      • 2015-12-06
      • 1970-01-01
      • 2015-03-27
      • 2011-12-28
      相关资源
      最近更新 更多