-
Bug
-
Resolution: Fixed
-
P3
-
7
-
b94
-
generic
-
generic
-
Verified
new Random() promises this:
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
but if there are concurrent calls to new Random(), it does not
do very well at fulfilling its contract.
The following program should print out a number much closer to 0.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
public class RandomSeedCollisions {
public static void main(String[] args) throws Throwable {
class RandomCollector implements Runnable {
long[] randoms = new long[1<<16];
public void run() {
for (int i = 0; i < randoms.length; i++)
randoms[i] = new Random().nextLong();
}};
final int threadCount = 2;
List<RandomCollector> collectors = new ArrayList<RandomCollector>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < threadCount; i++) {
RandomCollector r = new RandomCollector();
collectors.add(r);
threads.add(new Thread(r));
}
for (Thread thread : threads)
thread.start();
for (Thread thread : threads)
thread.join();
int collisions = 0;
HashSet<Long> s = new HashSet<Long>();
for (RandomCollector r : collectors) {
for (long x : r.randoms) {
if (s.contains(x))
collisions++;
s.add(x);
}
}
System.out.printf("collisions=%d%n", collisions);
if (collisions > 10)
throw new Error("too many collisions");
}
}
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
but if there are concurrent calls to new Random(), it does not
do very well at fulfilling its contract.
The following program should print out a number much closer to 0.
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
public class RandomSeedCollisions {
public static void main(String[] args) throws Throwable {
class RandomCollector implements Runnable {
long[] randoms = new long[1<<16];
public void run() {
for (int i = 0; i < randoms.length; i++)
randoms[i] = new Random().nextLong();
}};
final int threadCount = 2;
List<RandomCollector> collectors = new ArrayList<RandomCollector>();
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < threadCount; i++) {
RandomCollector r = new RandomCollector();
collectors.add(r);
threads.add(new Thread(r));
}
for (Thread thread : threads)
thread.start();
for (Thread thread : threads)
thread.join();
int collisions = 0;
HashSet<Long> s = new HashSet<Long>();
for (RandomCollector r : collectors) {
for (long x : r.randoms) {
if (s.contains(x))
collisions++;
s.add(x);
}
}
System.out.printf("collisions=%d%n", collisions);
if (collisions > 10)
throw new Error("too many collisions");
}
}
- relates to
-
JDK-6955840 ThreadLocalRandom bug - overridden setSeed(long) method is not invoked for java.util.Random(long)
-
- Closed
-
-
JDK-8201634 Random seedUniquifier uses incorrect LCG
-
- Resolved
-