Random vs ThreadLocalRandom Classes in Java
The Random Class of the java.util package is used for generating a stream of pseudorandom numbers. It uses a 48-bit seed, which is amended by implementing a Linear Congruential Formula. The general form of a Linear Congruential Formula is an+1 = k * an + c (mod m) where a0 is the seed, a1, a2, … an, an+1 are the random numbers and k, c, m are constants.
If we create two instances of the Random class with the same seed value and call the same sequence of methods for each, they both will return identical sequences of numbers. This property is enforced by specific algorithms defined for this class. The algorithms use a protected utility method which upon invocation can give up to 32 pseudorandomly generated bits. Instances of Random are thread–safe. Although, if the same instances are used across threads they may suffer from contention and result in poor performance. The Instances of Random are not cryptographically safe and therefore should not be used for security-sensitive applications.
public class Random extends Object implements Serializable
Let us take an example, in the program given below we have three instances of the Random class. The first two have the same seed value passed into its constructor. This results in the same number getting generated when we use the nextInt() method of the Random class. But when we change the value of the seed and use it to create the third instance, the number getting generated is different. This example clearly demonstrates the above-stated fact about the instances generating the same sequence of numbers if the same seed value is used and the same methods are used for both.
-1148559096 -1148559096 -1167027043
Now dwelling onto the next class that is our ThreadLocalRandom class
ThreadLocalRandom class present inside the java.util package is also used for generating a stream of pseudo-random numbers. It is a sub-class of the Random class discussed above. As the name suggests this class generates random numbers isolated to the current thread. A ThreadLocalRandom is initialized using an internally generated seed value that is not otherwise modifiable. Using ThreadLocalRandom instead of shared instances of Random will result in low contention and overhead. ThreadLocalRandom, just like its parent class, is not cryptographically secure.
public class ThreadLocalRandom extends Random
Implementation: Let us take a scenario where we are creating two simple threads in the main. Inside the run() method we call the ThreadLocalRandom.current.nextInt(). Both the threads use the same value of seed i.e. 10 but give different results because the call to nextInt() is isolated by the thread execution.
Thread 12 generated 7 Thread 11 generated 0
Now we are done with discussing both the classes and have an adequate understanding of both of them. Now wrapping up the article by concluding out the differences between them.
Random ThreadLocalRandom If different threads use the same instance of Random it results in contention and consequent performance degradation. There is no contention because the random numbers generated are local to the current thread. Uses Linear Congruential Formula to modify its seed value. The Random generator is initialized using an internally generated seed. Useful in applications where each thread has its own set of Random instances to use. Useful in applications where multiple threads use random numbers in parallel in thread pools. This is the Parent class. This is the Child class.