This post examines differences between java.util.Random, java.security.SecureRandom and java.util.concurrent.ThreadLocalRandom and tells when to use which one of the classes to use to generate random numbers.
In Java, using java.util.Random
, java.security.SecureRandom
, and java.util.concurrent.ThreadLocalRandom
, we can generate random numbers.
In this tutorial, let's examine the differences between these classes and when to use each.
1. java.util.Random
The Random
class is used to generate a stream of pseudo-random numbers. It is simpler to use and suitable for many applications.
Here is an example of how to generate a random number using java.util.Random
class.
import java.util.Random;
public class RandomTest {
public static void main(String[] args) {
Random random = new Random();
int randomNumber = random.nextInt(11);
System.out.println("Random number: " + randomNumber);
}
}
But there are two downsides to it:
- Not cryptographically secure
- Not performant efficient when used in multi-threaded environments
SecureRandom
and ThreadLocalRandom
are the two classes that can be used to overcome the above problems.
2. java.security.SecureRandom
SecureRandom
is a subclass of java.util.Random
and is the preferred choice to generate random numbers in security-sensitive applications. It uses a cryptographically strong pseudorandom generator to generate random numbers.
This CSRNG (Cryptographically Strong Random Number Generator) complies with the security requirements of Cryptography modules and all the random numbers generated are cryptographically strong and unpredictable.
Here is an example of how to generate random numbers using SecureRandom
class.
package random;
import java.security.SecureRandom;
public class SecureRandomTest {
public static void main(String[] args) {
SecureRandom secureRandom = new SecureRandom();
int randomInt = secureRandom.nextInt();
System.out.println("Random number: " + randomInt);
}
}
3. java.util.concurrent.ThreadLocalRandom
java.util.concurrent.ThreadLocalRandom
is a subclass of java.util.Random
that is optimized for multi-threaded environments. It uses thread-local storage to generate random numbers so that each thread can generate its own sequence of random numbers without interference from other threads.
You can use the current()
method to obtain the current instance of the ThreadLocalRandom
class and then use the various methods provided by the class to generate random numbers. Here are a few examples:
package random;
import java.util.concurrent.ThreadLocalRandom;
public class ThreadLocalRandomTest {
public static void main(String[] args) {
int randomInt = ThreadLocalRandom.current().nextInt(100);
System.out.println("Random integer: " + randomInt);
double randomDouble = ThreadLocalRandom.current().nextDouble();
System.out.println("Random double: " + randomDouble);
long randomLong = ThreadLocalRandom.current().nextLong(1000000);
System.out.println("Random long: " + randomLong);
}
}
4. Conclusion
In general, if you need to generate random numbers for cryptography, you should use java.security.SecureRandom
. If you need to generate random numbers in a multi-threaded environment with no thread congestion and no performance penalty, you should use java.util.concurrent.ThreadLocalRandom
. Otherwise, if you just need to generate random numbers for general-purpose applications, you can use java.util.Random
.
CodeProject