--- jsr166/src/main/java/util/Random.java 2007/01/07 07:38:27 1.18 +++ jsr166/src/main/java/util/Random.java 2010/09/27 19:15:15 1.28 @@ -1,8 +1,26 @@ /* - * %W% %E% + * Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. - * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. */ package java.util; @@ -14,7 +32,7 @@ import sun.misc.Unsafe; * An instance of this class is used to generate a stream of * pseudorandom numbers. The class uses a 48-bit seed, which is * modified using a linear congruential formula. (See Donald Knuth, - * The Art of Computer Programming, Volume 3, Section 3.2.1.) + * The Art of Computer Programming, Volume 2, Section 3.2.1.) *

* If two instances of {@code Random} are created with the same * seed, and the same sequence of method calls is made for each, they @@ -32,8 +50,19 @@ import sun.misc.Unsafe; *

* Many applications will find the method {@link Math#random} simpler to use. * + *

Instances of {@code java.util.Random} are threadsafe. + * However, the concurrent use of the same {@code java.util.Random} + * instance across threads may encounter contention and consequent + * poor performance. Consider instead using + * {@link java.util.concurrent.ThreadLocalRandom} in multithreaded + * designs. + * + *

Instances of {@code java.util.Random} are not cryptographically + * secure. Consider instead using {@link java.security.SecureRandom} to + * get a cryptographically secure pseudo-random number generator for use + * by security-sensitive applications. + * * @author Frank Yellin - * @version %I%, %G% * @since 1.0 */ public @@ -45,14 +74,12 @@ class Random implements java.io.Serializ * The internal state associated with this pseudorandom number generator. * (The specs for the methods in this class describe the ongoing * computation of this value.) - * - * @serial */ private final AtomicLong seed; - private final static long multiplier = 0x5DEECE66DL; - private final static long addend = 0xBL; - private final static long mask = (1L << 48) - 1; + private static final long multiplier = 0x5DEECE66DL; + private static final long addend = 0xBL; + private static final long mask = (1L << 48) - 1; /** * Creates a new random number generator. This constructor sets @@ -102,7 +129,7 @@ class Random implements java.io.Serializ synchronized public void setSeed(long seed) { seed = (seed ^ multiplier) & mask; this.seed.set(seed); - haveNextNextGaussian = false; + haveNextNextGaussian = false; } /** @@ -134,9 +161,9 @@ class Random implements java.io.Serializ long oldseed, nextseed; AtomicLong seed = this.seed; do { - oldseed = seed.get(); - nextseed = (oldseed * multiplier + addend) & mask; - } while (!seed.weakCompareAndSet(oldseed, nextseed)); + oldseed = seed.get(); + nextseed = (oldseed * multiplier + addend) & mask; + } while (!seed.compareAndSet(oldseed, nextseed)); return (int)(nextseed >>> (48 - bits)); } @@ -160,11 +187,11 @@ class Random implements java.io.Serializ * @since 1.1 */ public void nextBytes(byte[] bytes) { - for (int i = 0, len = bytes.length; i < len; ) - for (int rnd = nextInt(), - n = Math.min(len - i, Integer.SIZE/Byte.SIZE); - n-- > 0; rnd >>= Byte.SIZE) - bytes[i++] = (byte)rnd; + for (int i = 0, len = bytes.length; i < len; ) + for (int rnd = nextInt(), + n = Math.min(len - i, Integer.SIZE/Byte.SIZE); + n-- > 0; rnd >>= Byte.SIZE) + bytes[i++] = (byte)rnd; } /** @@ -186,7 +213,7 @@ class Random implements java.io.Serializ * value from this random number generator's sequence */ public int nextInt() { - return next(32); + return next(32); } /** @@ -237,11 +264,11 @@ class Random implements java.io.Serializ * successive calls to this method if n is a small power of two. * * @param n the bound on the random number to be returned. Must be - * positive. + * positive. * @return the next pseudorandom, uniformly distributed {@code int} * value between {@code 0} (inclusive) and {@code n} (exclusive) * from this random number generator's sequence - * @exception IllegalArgumentException if n is not positive + * @throws IllegalArgumentException if n is not positive * @since 1.2 */ @@ -301,11 +328,11 @@ class Random implements java.io.Serializ * * @return the next pseudorandom, uniformly distributed * {@code boolean} value from this random number generator's - * sequence + * sequence * @since 1.2 */ public boolean nextBoolean() { - return next(1) != 0; + return next(1) != 0; } /** @@ -392,7 +419,7 @@ class Random implements java.io.Serializ */ public double nextDouble() { return (((long)(next(26)) << 27) + next(27)) - / (double)(1L << 53); + / (double)(1L << 53); } private double nextNextGaussian; @@ -446,28 +473,28 @@ class Random implements java.io.Serializ synchronized public double nextGaussian() { // See Knuth, ACP, Section 3.4.1 Algorithm C. if (haveNextNextGaussian) { - haveNextNextGaussian = false; - return nextNextGaussian; - } else { + haveNextNextGaussian = false; + return nextNextGaussian; + } else { double v1, v2, s; - do { + do { v1 = 2 * nextDouble() - 1; // between -1 and 1 - v2 = 2 * nextDouble() - 1; // between -1 and 1 + v2 = 2 * nextDouble() - 1; // between -1 and 1 s = v1 * v1 + v2 * v2; - } while (s >= 1 || s == 0); - double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s); - nextNextGaussian = v2 * multiplier; - haveNextNextGaussian = true; - return v1 * multiplier; + } while (s >= 1 || s == 0); + double multiplier = StrictMath.sqrt(-2 * StrictMath.log(s)/s); + nextNextGaussian = v2 * multiplier; + haveNextNextGaussian = true; + return v1 * multiplier; } } /** * Serializable fields for Random. * - * @serialField seed long; + * @serialField seed long * seed for random computations - * @serialField nextNextGaussian double; + * @serialField nextNextGaussian double * next Gaussian to be returned * @serialField haveNextNextGaussian boolean * nextNextGaussian is valid @@ -487,9 +514,9 @@ class Random implements java.io.Serializ ObjectInputStream.GetField fields = s.readFields(); - // The seed is read in as {@code long} for - // historical reasons, but it is converted to an AtomicLong. - long seedVal = (long) fields.get("seed", -1L); + // The seed is read in as {@code long} for + // historical reasons, but it is converted to an AtomicLong. + long seedVal = fields.get("seed", -1L); if (seedVal < 0) throw new java.io.StreamCorruptedException( "Random: invalid seed"); @@ -502,12 +529,12 @@ class Random implements java.io.Serializ * Save the {@code Random} instance to a stream. */ synchronized private void writeObject(ObjectOutputStream s) - throws IOException { + throws IOException { // set the values of the Serializable fields ObjectOutputStream.PutField fields = s.putFields(); - // The seed is serialized as a long for historical reasons. + // The seed is serialized as a long for historical reasons. fields.put("seed", seed.get()); fields.put("nextNextGaussian", nextNextGaussian); fields.put("haveNextNextGaussian", haveNextNextGaussian); @@ -523,7 +550,7 @@ class Random implements java.io.Serializ try { seedOffset = unsafe.objectFieldOffset (Random.class.getDeclaredField("seed")); - } catch (Exception ex) { throw new Error(ex); } + } catch (Exception ex) { throw new Error(ex); } } private void resetSeed(long seedVal) { unsafe.putObjectVolatile(this, seedOffset, new AtomicLong(seedVal));