Math.random() static method

The generated random number is a double between 0 and 1, i.e. 0 <= random <= 1.

Use:

for (int i = 0; i < 10; i++) { System.out.println(Math.random()); }Copy the code

Results:

0.3598613895606426 0.2666778145365811 0.25090731064243355 0.011064998061666276 0.600686228175639 0.9084006027629496 0.12700524654847833 0.6084605849069343 0.7290804782514261 0.9923831908303121

Implementation principle:

When this method is first called, it creates a single new pseudorandom-number generator, exactly as if by the expression new java.util.Random() This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.

When the math.random () method is called for the first time, a pseudo-random number generator is automatically created, actually using new java.util.random (). This new pseudo-random number generator is used when the math.random () method is next called.

The source code is as follows:

public static double random() { Random rnd = randomNumberGenerator; if (rnd == null) rnd = initRNG(); NextDouble (); return rnd.nextdouble (); }private static synchronized Random initRNG() { Random rnd = randomNumberGenerator; return (rnd == null) ? (randomNumberGenerator = new Random()) : rnd; // New java.util.random ()}Copy the code

This method is properly synchronized to allow correct use by more than one thread. However, if many threads need to generate pseudorandom numbers at a great rate, it may reduce contention for each thread to have its own pseudorandom-number generator.

The initRNG() method is synchronized, so in the case of multiple threads, only one thread is responsible for creating the pseudo-random number generator (using the current time as the seed), which is used by other threads to generate random numbers.

soMath.random()Methods are thread-safe.

When the random number generation thread is not safe:

  • Thread 1 produces a generator generator1 on the first call to Random (), using the current time as the seed.

  • Thread 2 produces a generator generator2 on the first call to Random (), using the current time as the seed.

  • It just so happens that Generator1 and Generator2 use the same seed, causing the random numbers generated after Generator1 to be the same as the random numbers generated after Generator2 every time.

When is the generation of random numbers thread-safe: math.random () static method used

  • Thread 1 produces a generator generator1 on the first call to Random (), using the current time as the seed.

  • When thread 2 first calls Random () and finds that there is already a generator generator1, it uses generator Generator1 directly.

    public class JavaRandom { public static void main(String args[]) { new MyThread().start(); new MyThread().start(); }}class MyThread extends Thread { public void run() { for (int i = 0; i < 2; i++) { System.out.println(Thread.currentThread().getName() + “: ” + Math.random()); }}}

Results:

Thread-1: 0.8043581595645333 Thread-0: 0.9338269554390357 Thread-1: 0.5571569413128877 Thread-0: 0.37484586843392464

2. Java.util. Random utility class

Basic algorithm: Linear congruent Pseudorandom Number Generator (LGC) Pseudo-random number generator **** Disadvantage: predictability

An attacker will simply compute the seed from the output values observed. This takes

significantly less

time than 2^48 in the case of java.util.Random. The seed value can be easily calculated from the output. It is shown that you can predict future Random outputs observing only two(!) output values in time roughly 2^16. So you can predict the random number of the next output. ** In applications that focus on information security, do not use LCG algorithm to generate random numbers. Use SecureRandom instead.

Use:

Random random = new Random(); for (int i = 0; i < 5; i++) { System.out.println(random.nextInt()); }Copy the code

Results:

-24520987 -96094681 -952622427 300260419 1489256498

The Random class defaults to using the current system clock as its seed:

public Random() { this(seedUniquifier() ^ System.nanoTime()); }public Random(long seed) { if (getClass() == Random.class) this.seed = new AtomicLong(initialScramble(seed)); else { // subclass might have overriden setSeed this.seed = new AtomicLong(); setSeed(seed); }}Copy the code

The Random class provides a method: API

  • NextBoolean () – Returns true or false for uniform distribution

  • nextBytes(byte[] bytes)

  • NextDouble () – Returns evenly distributed doubles between 0.0 and 1.0

  • NextFloat () – Returns evenly distributed floats between 0.0 and 1.0

  • NextGaussian ()- Returns a double for a Gaussian(i.e. normal) distribution between 0.0 and 1.0

  • NextInt () – Returns a uniformly distributed int

  • NextInt (int n) – Returns uniformly distributed int between 0 and n (including 0, excluding n)

  • NextLong () – Returns evenly distributed longs

  • SetSeed (Long seed) – Sets the seed

As long as the seed is the same, the generated random number is the same: because the seed is certain, the random number algorithm is also certain, so the output is certain!

Random random1 = new Random(10000); Random random2 = new Random(10000); for (int i = 0; i < 5; i++) { System.out.println(random1.nextInt() + " = " + random2.nextInt()); }Copy the code

Results:

-498702880 = -498702880 -858606152 = -858606152 1942818232 = 1942818232 -1044940345 = -1044940345 1588429001 = 1588429001

3. Java. Util. Concurrent. ThreadLocalRandom tools

ThreadLocalRandom was provided after JDK 7 and is also inherited from java.util.random.

private static final ThreadLocal<ThreadLocalRandom> localRandom =    new ThreadLocal<ThreadLocalRandom>() {        protected ThreadLocalRandom initialValue() {            return new ThreadLocalRandom();        }};
Copy the code

Each thread has an independent random number generator, which is used to generate random numbers concurrently and can solve the competition among multiple threads. ** more efficient! For more tutorials on Java utility classes, click here.

Instead of instantiating ThreadLocalRandom directly with new, ThreadLocalRandom is instantiated for the first time with its static method current(). We then call the methods provided by the java.util.Random class to get the various Random numbers.

Use:

public class JavaRandom { public static void main(String args[]) { new MyThread().start(); new MyThread().start(); }}class MyThread extends Thread { public void run() { for (int i = 0; i < 2; i++) { System.out.println(Thread.currentThread().getName() + ": " + ThreadLocalRandom.current().nextDouble()); }}}Copy the code

Results:

Thread0:0.13267085355389086 Thread1:0.1138484950410098 Thread0:0.17187774671469858 Thread1:0.9305225910262372

4. java.Security.SecureRandom

Also inherited to java.util.random.

Instances of java.util.Random are not cryptographically secure. Consider instead using SecureRandom to get a cryptographically secure pseudo-random number generator for use by security-sensitive applications.SecureRandom takes Random Data from your os (they can be interval between keystrokes etc – most os collect these data store them in files – /dev/random and /dev/urandom in case of linux/solaris) and uses that as the seed. The operating system collects random events such as mouse clicks, keyboard clicks and so on, and SecureRandom uses these random events as seeds.

SecureRandom provides an encrypted strong random number generator (RNG) that requires that the seed be unpredictable and produce nondeterministic output. SecureRandom also provides implementation-independent algorithms, so the caller (application code) requests a particular RNG algorithm and passes it back to the Algorithm’s SecureRandom object.

  • If only the algorithm name is specified, the following output is displayed: SecureRandom Random = Securerandom.getInstance (“SHA1PRNG”);

  • If both the algorithm name and the package provider are specified, the following is displayed: SecureRandom Random = Securerandom.getInstance (“SHA1PRNG”, “SUN”);

Use:

SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG"); SecureRandom random2 = SecureRandom.getInstance("SHA1PRNG"); for (int i = 0; i < 5; i++) { System.out.println(random1.nextInt() + " ! = " + random2.nextInt()); }Copy the code

Results:

704046703! = 2117229935, 60819811. = 107252259, 425075610. = 682299589-295395347! = – 1637998900-1147654329! = 1418666937

5. Random string

You can use the RandomStringUtils class in the Apache Commons-lang package. Maven has the following dependencies:

< the dependency > < groupId > Commons - lang < / groupId > < artifactId > Commons - lang < / artifactId > < version > 2.6 < / version > < / dependency >Copy the code

API reference: commons.apache.org/proper/comm…

Example:

public class RandomStringDemo {    public static void main(String[] args) {        // Creates a 64 chars length random string of number.        String result = RandomStringUtils.random(64, false, true);        System.out.println("random = " + result);        // Creates a 64 chars length of random alphabetic string.        result = RandomStringUtils.randomAlphabetic(64);        System.out.println("random = " + result);        // Creates a 32 chars length of random ascii string.        result = RandomStringUtils.randomAscii(32);        System.out.println("random = " + result);        // Creates a 32 chars length of string from the defined array of        // characters including numeric and alphabetic characters.        result = RandomStringUtils.random(32, 0, 20, true, true, "qw32rfHIJk9iQ8Ud7h0X".toCharArray());        System.out.println("random = " + result);    }}
Copy the code

The RandomStringUtils class also relies on the java.util.Random utility class:

Reference:

  • yangzb.iteye.com/blog/325264

  • Stackoverflow.com/questions/1…