问题 Java 7:ThreadLocalRandom生成相同的随机数


我正在尝试使用Java 7 ThreadLocalRandom 并且看到它在多个线程中生成完全相同的随机数。

这是我的代码,我创建了5个线程,每个线程打印出5个随机数:

//5 threads
for(int i = 0; i < 5 ; i++) {
    final Thread thread = new Thread() {
        @Override
        public void run() {
            System.out.print(Thread.currentThread().getName()+":");

            //each thread prints 5 random numbers
            for(int j = 0 ; j < 5; j++) {
                final int random = ThreadLocalRandom.current().nextInt(1,100);
                System.out.print(random + ",");
            }
            System.out.println();
        }
    };
    thread.start();
    thread.join();
}

输出:

Thread-0:1,93,45,75,29,
Thread-1:1,93,45,75,29,
Thread-2:1,93,45,75,29,
Thread-3:1,93,45,75,29,
Thread-4:1,93,45,75,29,

为什么我为每个线程和每次执行程序获得相同的随机数?


2473
2017-08-21 16:27


起源



答案:


似乎有一个关于这个问题的公开错误。看到 这里 和 这里


10
2017-08-21 16:32



+1漂亮的东西错误 - Matt
该错误已在JDK7的Update 2中得到解决。在这里下载: oracle.com/technetwork/java/javase/downloads/... - jopasserat


答案:


似乎有一个关于这个问题的公开错误。看到 这里 和 这里


10
2017-08-21 16:32



+1漂亮的东西错误 - Matt
该错误已在JDK7的Update 2中得到解决。在这里下载: oracle.com/technetwork/java/javase/downloads/... - jopasserat


谷歌搜索“ThreadLocalRandom源”给了我 http://www.assembla.com/code/scala-eclipse-toolchain/git/nodes/src/forkjoin/scala/concurrent/forkjoin/ThreadLocalRandom.java

长/短:它使用了 ThreadLocal<ThreadLocalRandom> 它调用no-arg构造函数进行构造

no-arg构造函数是

/**
 * Constructor called only by localRandom.initialValue.
 * We rely on the fact that the superclass no-arg constructor
 * invokes setSeed exactly once to initialize.
 */
ThreadLocalRandom() {
    super();
}

no-arg super in 随机 用一个独特的种子调用这个(长)

不过那个构造函数呢

public Random(long seed) {
    this.seed = new AtomicLong(initialScramble(seed));
}

即不是文档的预期行为

和ThreadLocalRandom不/不能使用私有 seed


5
2017-08-21 16:47



这不是JDK的来源(请注意 eclipse 和 scala URL中的提示)。真正的JDK源代码是 hg.openjdk.java.net,这是 ThreadLocalRandom - dimo414


这不是因为线程是在大致相同的时间创建的,因此从计时器中获取相同的值吗?虽然我可能弄错了,但我的印象是它的工作原理。


1
2017-08-21 16:31



这不是同一时间,存在很大的时间差异 - 每个线程仅在前一个线程终止后创建。 - MByD