Random
在多个线程之间共享该类的一个实例是否有效?并nextInt(int)
特别从多个线程调用?
java.util.concurrent.ThreadLocalRandom
。
Random
在多个线程之间共享该类的一个实例是否有效?并nextInt(int)
特别从多个线程调用?
java.util.concurrent.ThreadLocalRandom
。
Answers:
从某种意义上讲,它是线程安全的,当被多个线程使用时,它仍然会生成随机数。
Sun / Oracle JVM实现使用同步和AtomicLong作为种子来提高线程之间的一致性。但是,文档中似乎并没有在所有平台上对此进行担保。
我不会编写要求这种保证的程序,尤其是在您无法确定nextInt()
调用顺序时。
尽管并非总是如此,但它是线程安全的。
有关更多详细信息,请参见http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6362070。
根据文档,Math.random()保证可以安全地被多个线程使用。但是Random类却没有。我认为您必须自己进行同步。
是的,Random是线程安全的。该nextInt()
方法调用受保护的next(int)
方法,该方法使用AtomicLong seed, nextseed
(原子长)来生成下一个种子。AtomicLong
用于种子生成时的线程安全。
如前所述,这是节省线程的,但是java.util.concurrent.ThreadLocalRandom
根据本文的用法(链接失效)可能是明智的。ThreadLocalRandom还是Random的子类,因此它向后兼容。
该文章链接了不同Random类的比较分析结果
java.util.Random
,java.util.concurrent.ThreadLocalRandom
和java.lang.ThreadLocal<java.util.Random>
。结果表明,使用ThreadLocalRandom的性能最高,其次是ThreadLocal,而性能最差的Random本身。
在不假设Random使用原子变量的情况下,这是我处理问题的方式。如果currentTime * thread id
将来某个时间相等,它仍然可以随机碰撞,但这对于我的需求来说已经足够了。为了真正避免冲突的可能性,您可以让每个请求都等待唯一的时钟时间戳。
/**
* Thread-specific random number generators. Each is seeded with the thread
* ID, so the sequence of pseudo-random numbers are unique between threads.
*/
private static ThreadLocal<Random> random = new ThreadLocal<Random>() {
@Override
protected Random initialValue() {
return new Random(
System.currentTimeMillis() *
Thread.currentThread().getId());
}
};
(24*60*60*1000)
重要吗?
(24*60*60*1000)
是如此,与ID的线程12
在xxxxxxxxxx045
米利斯没有获得种子一样线程22
在xxxxxxxxxx035
米利斯。但是,我没有充分的理由认为线程ID是增量的,也没有充分的理由认为我明天将在比今天更多的随机时间创建线程。我现在简化了算法,并更新了说明以找出缺点。