Concurrent random number generation in Java
在Web服务器上,许多线程正在向客户机提供内容。A/B测试是在网站上执行的,因此我们需要一个prng来为每个会话和测试选择一个变量。显然,当使用一个prng实例时,它是并发访问的,因此可能需要适当的锁定或其他机制。
最初我们使用了
从这样一个池中生成的随机数是否与从单个prng实例中生成的随机数一样好?
另一种方法是使用单个prng实例从中预生成值流,例如使用
哪种解决方案在性能方面更有效?
通过将结果传递给
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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) { } } } |
为了避免同步问题,每个线程都有一个RNG。为了避免特定于线程的RNG给出相同的输出,让主RNG为特定于线程的RNG生成一系列初始种子。这可能需要向代码中传递一个额外的种子参数来生成一个新线程。
您将需要测试自己在套件上运行RNG的不同选项的速度。如果需要,可以为主RNG和特定于线程的RNG使用不同的RNG引擎。一般来说,为特定于线程的RNG选择具有快速设置时间的RNG。这对主RNG来说并不重要,因为它只设置了一次。