Concurrent calls to new Random() not random enough

Xueming Shen Xueming.Shen at Sun.COM
Wed Mar 24 17:42:10 UTC 2010


6937857: Concurrent calls to new Random() not random enough

Martin Buchholz wrote:
> [+fy, jeremymanson]
>
> Here's a much better test case,
> and a proposed fix:
>
> http://cr.openjdk.java.net/~martin/webrevs/openjdk7/RandomSeedCollisions
>
> This adds some initialization overhead, but also removes some
> since
> new Random()
> no longer invokes a synchronized method.
>
> ----
> import java.util.*;
>
> public class RandomSeed {
>     public static void main(String[] args) throws Throwable {
>         class RandomCollector implements Runnable {
>             long[] randoms = new long[1<<22];
>             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);
>     }
> }
>
>
> On Tue, Mar 23, 2010 at 15:50, Martin Buchholz <martinrb at google.com> wrote:
>   
>> Hi Sherman,
>>
>> This is a bug report (sorry, no fix this time)
>>
>> Synopsis: Concurrent calls to new Random() not random enough
>> Description:
>> 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.*;
>>
>> public class RandomSeed {
>>    public static void main(String[] args) throws Throwable {
>>        class RandomCollector implements Runnable {
>>            int[] randoms = new int[1<<21];
>>            public void run() {
>>                for (int i = 0; i < randoms.length; i++)
>>                    randoms[i] = new Random().nextInt();
>>            }};
>>        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<Integer> s = new HashSet<Integer>();
>>        for (RandomCollector r : collectors) {
>>            for (int x : r.randoms) {
>>                if (s.contains(x))
>>                    collisions++;
>>                s.add(x);
>>            }
>>        }
>>        System.out.println(collisions);
>>    }
>> }
>> ---
>> ==> javac -source 1.6 -Xlint:all RandomSeed.java
>> ==> java -esa -ea RandomSeed
>> 876
>>
>>     




More information about the core-libs-dev mailing list