src/java.base/share/classes/java/util/Random.java
branchJDK-8193209-branch
changeset 57437 f02ffcb61dce
parent 57388 b1e6bc96af3d
child 57547 56cbdc3ea079
equal deleted inserted replaced
57436:b0c958c0e6c6 57437:f02ffcb61dce
     1 /*
     1 /*
     2  * Copyright (c) 1995, 2013, 2019, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 1995, 2019, Oracle and/or its affiliates. All rights reserved.
     3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
     5  *
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
     6  *
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
     7  *
    20  *
     8  *
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
     9  *
    22  * or visit www.oracle.com if you need additional information or have any
    10  *
    23  * questions.
    11  *
       
    12  *
       
    13  *
       
    14  *
       
    15  *
       
    16  *
       
    17  *
       
    18  *
       
    19  *
       
    20  *
       
    21  *
       
    22  *
       
    23  *
       
    24  */
    24  */
    25 
    25 
    26 package java.util;
    26 package java.util;
       
    27 
       
    28 import jdk.internal.misc.Unsafe;
    27 
    29 
    28 import java.io.*;
    30 import java.io.*;
    29 import java.math.BigInteger;
    31 import java.math.BigInteger;
       
    32 import java.util.Objects;
       
    33 import java.util.ServiceLoader;
       
    34 import java.util.ServiceLoader.Provider;
    30 import java.util.concurrent.atomic.AtomicLong;
    35 import java.util.concurrent.atomic.AtomicLong;
    31 import java.util.function.DoubleConsumer;
    36 import java.util.function.Function;
    32 import java.util.function.IntConsumer;
    37 import java.util.random.AbstractSharedRNG;
    33 import java.util.function.LongConsumer;
    38 import java.util.random.RandomNumberGenerator;
    34 import java.util.stream.DoubleStream;
    39 import java.util.stream.Collectors;
    35 import java.util.stream.IntStream;
       
    36 import java.util.stream.LongStream;
       
    37 import java.util.stream.StreamSupport;
       
    38 
       
    39 import jdk.internal.misc.Unsafe;
       
    40 
    40 
    41 /**
    41 /**
    42  * An instance of this class is used to generate a stream of
    42  * An instance of this class is used to generate a stream of
    43  * pseudorandom numbers. The class uses a 48-bit seed, which is
    43  * pseudorandom numbers. The class uses a 48-bit seed, which is
    44  * modified using a linear congruential formula. (See Donald Knuth,
    44  * modified using a linear congruential formula. (See Donald Knuth,
    74  *
    74  *
    75  * @author  Frank Yellin
    75  * @author  Frank Yellin
    76  * @since   1.0
    76  * @since   1.0
    77  */
    77  */
    78 public
    78 public
    79 class Random extends AbstractSharedRng implements java.io.Serializable {
    79 class Random extends AbstractSharedRNG implements java.io.Serializable {
    80     /** use serialVersionUID from JDK 1.1 for interoperability */
    80     /** use serialVersionUID from JDK 1.1 for interoperability */
    81     static final long serialVersionUID = 3905348978240129619L;
    81     static final long serialVersionUID = 3905348978240129619L;
    82 
    82 
    83     /**
    83     /**
    84      * The internal state associated with this pseudorandom number generator.
    84      * The internal state associated with this pseudorandom number generator.
   205             nextseed = (oldseed * multiplier + addend) & mask;
   205             nextseed = (oldseed * multiplier + addend) & mask;
   206         } while (!seed.compareAndSet(oldseed, nextseed));
   206         } while (!seed.compareAndSet(oldseed, nextseed));
   207         return (int)(nextseed >>> (48 - bits));
   207         return (int)(nextseed >>> (48 - bits));
   208     }
   208     }
   209 
   209 
   210     static final BigInteger thePeriod = BigInteger.valueOf(1L<<48);  // Period is 2**48
   210     /*
       
   211      * Period of Random is 2**48
       
   212      */
       
   213     private static final BigInteger PERIOD = BigInteger.valueOf(1L<<48);
   211 
   214 
   212     /**
   215     /**
   213      * Returns the period of this random number generator.
   216      * Returns the period of this random number generator.
   214      *
   217      *
   215      * @return the period of this random number generator.
   218      * @return the period of this random number generator.
   216      */
   219      */
   217     public BigInteger period() {
   220     public BigInteger period() {
   218 	// Here we also take care of checking for instances of class SecureRandom,
   221         return PERIOD;
   219 	// just so as not to bother the implementors of that class.
       
   220 	// (Any specific instance of SecureRandom can of course override this method.)
       
   221 	// The cast to (Object) is of course needed only during development.
       
   222 	return ((Object)this instanceof java.security.SecureRandom) ? Rng.HUGE_PERIOD : thePeriod;
       
   223     }
   222     }
   224 
   223 
   225     /**
   224     /**
   226      * Generates random bytes and places them into a user-supplied
   225      * Generates random bytes and places them into a user-supplied
   227      * byte array.  The number of random bytes produced is equal to
   226      * byte array.  The number of random bytes produced is equal to
   494             return v1 * multiplier;
   493             return v1 * multiplier;
   495         }
   494         }
   496     }
   495     }
   497 
   496 
   498     /**
   497     /**
       
   498      * Creates a new random number generator that uses the random number generator algorithm
       
   499      * specified by name. The seed of the random number generator to a value very likely to be
       
   500      * distinct from any other invocation.
       
   501      *
       
   502      * @param name  name of random number generator algorithm to use.
       
   503      *
       
   504      * @return an instance of random number generator.
       
   505      *
       
   506      * @throws IllegalArgumentException if {@code name} is an unknown random number generator
       
   507      *
       
   508      * @since 14
       
   509      */
       
   510     public static RandomNumberGenerator byName(String name) throws IllegalArgumentException {
       
   511         Objects.requireNonNull(name);
       
   512         Map<String, Provider<RandomNumberGenerator>> rngs = getRNGMap();
       
   513         Provider<RandomNumberGenerator> provider = rngs.get(name.toUpperCase());
       
   514         if (provider == null) {
       
   515             throw new IllegalArgumentException(name + " is an unknown random number generator");
       
   516         }
       
   517         return provider.get();
       
   518     }
       
   519 
       
   520     private static Map<String, Provider<RandomNumberGenerator>> rngMap;
       
   521 
       
   522     private static Map<String, Provider<RandomNumberGenerator>> getRNGMap() {
       
   523         if (rngMap == null) {
       
   524             synchronized (Random.class) {
       
   525                 if (rngMap == null) {
       
   526                     rngMap = ServiceLoader
       
   527                             .load(RandomNumberGenerator.class)
       
   528                             .stream()
       
   529                             .filter(p -> !p.type().isInterface())
       
   530                             .collect(Collectors.toMap(p -> p.type().getSimpleName().toUpperCase(),
       
   531                                     Function.identity()));
       
   532                 }
       
   533             }
       
   534         }
       
   535         return rngMap;
       
   536     }
       
   537 
       
   538     /**
   499      * Serializable fields for Random.
   539      * Serializable fields for Random.
   500      *
   540      *
   501      * @serialField    seed long
   541      * @serialField    seed long
   502      *              seed for random computations
   542      *              seed for random computations
   503      * @serialField    nextNextGaussian double
   543      * @serialField    nextNextGaussian double