首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java中并发随机数的生成

Java中并发随机数的生成
EN

Stack Overflow用户
提问于 2016-01-02 15:11:54
回答 2查看 2.1K关注 0票数 1

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

最初我们使用java.util.Random(juR),但是由于它有提到的缺陷,例如java.util.Random有多好?,所以我们尝试使用MersenneTwister。然而,由于Mersenne-Twister 依赖于内部状态的事实,我们看到了性能的大幅下降,因此它对nextInt()的访问需要同步。另一种选择可能是XOR shift PRNG,但它与Mersenne Twister有相同的问题。你可以在这里找到解释,例如:http://xorshift.di.unimi.it/

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

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

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

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-01-04 13:13:41

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

代码语言:javascript
复制
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) {
        }
    }

}
票数 3
EN

Stack Overflow用户

发布于 2016-01-02 16:26:00

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

您需要自己测试RNG在您的工具包上运行的速度有多快。如果需要,可以为主RNG和特定于线程的RNG使用不同的RNG引擎。通常,为线程特定的RNG选择具有快速设置时间的RNG。这对主RNG没有那么重要,因为它只设置了一次。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34567378

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档