What do we learn from books?
The most obvious and intuitive way is to generate random numbers in Java with a simple call:
java.lang.Math.random()
In all other languages, generating random numbers is like using Math tool classes such as abs, pow, floor, sqrt and other mathematical functions. Most people learn about this category through books, tutorials, and courses. A simple example: A double precision floating point number can be generated from 0.0 to 1.0. Then through the above information, the developer wants to generate a double-precision floating point number between 0.0 and 10.0 and write it like this:
Math.random() * 10
If an integer between 0 and 10 is generated, it will be written as:
Math.round(Math.random() * 10)
Advanced
By reading the source code of Math.random(), or simply using the IDE's automatic completion function, developers can easily find that java.lang.Math.random() uses an internal randomly generated object - a very powerful object can be flexible Random generation: Boolean values, all numeric types, and even Gaussian distributions. For example:
new java.util.Random().nextInt(10)
It has a disadvantage, that is, it is an object. Its method must be called through an instance, which means its constructor must be called first. If there is sufficient memory, expressions like the one above are acceptable; but when there is insufficient memory, it will cause problems.
A simple solution that can avoid creating a new instance every time a random number is to use a static class. You may have thought of java.lang.Math, very well, we are improving the initialization of java.lang.Math. Although this project is low, you also need to do some simple unit tests to make sure it doesn't go wrong.
Assuming that the program needs to generate a random number to store, the problem comes again. For example, sometimes it is necessary to operate or protect seeds, and an internal number is used to store state and calculate the next random number. In these special cases, it is inappropriate to share randomly generated objects.
concurrent
In the environment of Java EE multithreaded application, randomly generated instance objects can still be stored in a class or other implementation class as a static property. Fortunately, java.util.Random is thread-safe, so there is no risk that multiple thread calls will destroy the seed.
Another thing worth considering is the multithreaded instance of java.lang.ThreadLocal. The lazy approach is to implement a single instance through the Java itself API. Of course, you can also ensure that each thread has its own instance object.
Although Java does not provide a good way to manage a single instance of java.util.Random. However, the long-awaited Java 7 provides a new way to generate random numbers:
java.util.concurrent.ThreadLocalRandom.current().nextInt(10)
This new API combines the advantages of two other approaches: single instance/static access, as flexible as Math.random(). ThreadLocalRandom is also faster than any other way to handle high concurrency.
experience
Chris Marasti-Georg points out:
Math.round(Math.random() * 10)
Make the distribution unbalanced, for example: 0.0 - 0.499999 will round to 0, while 0.5 to 1.4999999 will round to 1. So how to use old style syntax to achieve a correct balanced distribution, as follows:
Math.floor(Math.random() * 11)
Fortunately, if we use java.util.Random or java.util.concurrent.ThreadLocalRandom, we don't have to worry about the above.
The Java practical project introduces some of the harms of incorrectly using the java.util.Random API. This lesson tells us not to use:
Math.abs(rnd.nextInt())%n
And use:
rnd.nextInt(n)
yThe above is a related introduction to n random numbers in Java, and I hope it will be helpful to everyone's learning.