出于某种原因,我曾经认为java.util.Random
是线程不安全的,一拉HashMap
或BitSet
,和Math.random()
被实现为包访问Random
与块,或ThreadLocalRandom.current().nextDouble()
。是否有任何理由从Java 8开始编写`new Random()`?
事实上,事实证明,java.util.Random
is thread-safe(通过原子)。因此,即使我需要在单个线程中进行一些随机输入,使用ThreadLocalRandom
也是有意义的,因为内部没有原子读取和写入,编译为锁定指令并发出内存屏障。而且,由于Java 8,ThreadLocalRandom
实质上是一个单例,所以它的状态保存在java.lang.Thread
类的一些字段中。因此方法ThreadLocalRandom.current()
不是对ThreadLocalMap
的访问,而只是一个静态字段读取,即。即非常便宜。
我有两个问题:
但从计算机科学一点,就是几个线性同余随机发生器(初始化的方法
ThreadLocalRandom
s为)的输出是相同的“随机”为输出单线性同余随机发生器(java.util.Random
实例)?如果回答第一个问题是肯定的,是有任何理由写的建设
new Random()
(不含种子),而不是ThreadLocalRandom.current()
,永远不会消失?
更新。我认为像ThreadLocalRandom.current().ints().parallel().collect(...)
这样的调用可能不正确,因为线程的随机生成器状态可能不会在ForkJoinPool
工作线程中初始化,但似乎ThreadLocalRandom
覆盖方法ints()
,longs()
和doubles()
,使上述构造正确。
你不能用ThreadLocalRandom写出http://stackoverflow.com/questions/15182496/why-does-this-code-using-random-strings-print-hello-world。 – immibis
@immibis好吧,它意味着唯一的情况 - 当我需要重现一些随机数序列时 – leventov
@immibis然而,问题是关于具体构造'new Random()',i。即没有种子。问题是开放的。 – leventov