java 随机数 多线程_关于多线程:Java中并发随机数的生成

在多线程环境下,讨论了如何安全地生成并发随机数,比较了java.util.Random和ThreadLocalRandom的使用。文章提到了Random的线程安全问题以及Mersenne Twister和XORShift PRNG的性能问题。建议使用ThreadLocalRandom以避免同步开销,并探讨了预生成随机数流的可能性。最后,提出了通过BlockingQueue实现线程安全的随机数生成器。
摘要由CSDN通过智能技术生成

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

最初我们使用了java.util.Random(jur),但由于它存在上述缺陷,例如java.util.random有多好,所以我们尝试使用mersennetwester。然而,由于Mersenne Twister依赖于内部状态,因此性能下降,因此需要同步访问nextInt()。另一种选择可能是xor-shift prng,但它与mersenne twister有相同的问题。您可以在以下位置找到解释:http://xorshift.di.unimi.it/

Random使用了compareAndset操作,该操作似乎更快,因为它不需要锁定,但根据javadoc类,它仍然不是线程安全的。相反,建议使用ThreadLocalRandom,这基本上会导致一个prng池。根据请求,一个随机可用线程处理https请求,因此从一组可用prng中选择一个随机prng。显然这非常快。

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

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

哪种解决方案在性能方面更有效?

对于这个应用程序(选择是否向用户显示a或b),只要随机数是均匀分布的,那么它们的质量实际上并不重要。

您正在努力进行预优化。Random被记录为线程安全的,与Web应用程序所需的所有IO(数据库查询、HTTP请求等)相比,每次启动会话时调用NextBoolean()的性能完全可以忽略。

在随机数质量方面,这个想法试图想出比java.util.random更好的方法。我们实际上有两个以上的变量,所以我们画整数。@亨利,就我所读到的,随机比特的概率分布不均匀。

即便如此,随机性还是足够好的。但如果你想要一个完美的分布,你甚至不需要随机分布。只需使用一个atomicinteger,并在每个会话开始时递增它。然后计算变量数的模。你只需要一个好的分布,而不是一个好的随机性。

但我的问题仍未得到解答。一个prng的池和一个prng一样好吗?

@我喜欢你简单的想法。但是,这只在进行1/N拆分时有效。如果我想对两个变体进行60/40%的分割,我想这是行不通的。

如果模5是0,1或2,选择版本A。如果是3或4,选择版本B。

让我们在聊天中继续讨论。

通过将结果传递给BlockingQueue,可以使任意随机数生成器线程安全。

class SafeRandom implements Runnable {

Random r = new Random();

BlockingQueue 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) {

}

}

}

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值