Java代码规范之避免多线程共享Random实例
目录
该条规范是什么
该规范指出在Java编程中,应避免多线程共享Random
实例。尽管共享Random
实例在并发环境下是线程安全的,但由于竞争相同的种子(seed)会导致性能下降。
为什么这么规定
以下是该规范的原因:
- 性能下降:当多个线程竞争相同的
Random
实例的种子(seed)时,会导致性能下降。这是因为种子的竞争可能会导致多个线程产生相同的随机数序列,从而降低了随机性和性能。 - 线程安全性:虽然
Random
实例本身是线程安全的,但多线程共享一个实例可能导致种子竞争问题,从而影响到线程安全和性能。
多种主要用法及其代码示例
使用ThreadLocalRandom(适用于JDK7及以上版本)
import java.util.concurrent.ThreadLocalRandom;
public class Example {
public void generateRandomNumber() {
int randomNum = ThreadLocalRandom.current().nextInt(0, 100);
System.out.println(randomNum);
}
}
每个线程持有一个Random实例(适用于JDK7之前版本)
import java.util.Random;
public class Example {
private static final ThreadLocal<Random> threadLocalRandom = ThreadLocal.withInitial(Random::new);
public void generateRandomNumber() {
Random random = threadLocalRandom.get();
int randomNum = random.nextInt(100);
System.out.println(randomNum);
}
}
其他类似规范
- 避免多线程共享
Random
实例的原则同样适用于使用Math.random()
方式生成随机数。在多线程环境中,推荐使用ThreadLocalRandom
或每个线程持有一个Random
实例来保证性能和线程安全。
详细区别
相较于多线程共享Random
实例,采用以下方法具有以下区别:
- 使用
ThreadLocalRandom
:ThreadLocalRandom
是JDK7及以上版本提供的线程安全的随机数生成器,不需要显式创建实例并且具有良好的性能。 - 每个线程持有一个
Random
实例:通过使用ThreadLocal
来维护每个线程独立的Random
实例,可以避免多线程竞争相同种子(seed)带来的性能问题,并保证线程安全。