【发布时间】: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