正在阅读Java 7的新功能,并发现这个新类已添加:
对于并发访问,使用ThreadLocalRandom代替 Math.random()会减少争用,最终会更好 性能
正在研究如何实施这项工作,从而减少争用和提高绩效。
答案 0 :(得分:3)
实际上,两者之间的区别在于同步。 Math#random()
可以由多个线程同时调用,因此必须同步,而ThreadLocalRandom
是Random
的非同步版本,它是线程绑定意味着每个线程获得自己的(更快)分配。
如果仔细查看实现,您会发现Math#random()
使用java.util.Random
的单个实例生成随机数,其中ThreadLocalRandom
为每个线程分配一个实例从这个意义上消除了争论。
ThreadLocalRandom
实现并发,Math#random()
实现同步。
答案 1 :(得分:0)
来自java DOCS:
ThreadLocalRandom
是与当前线程隔离的随机数生成器。与java.util.Random
类使用的全局java.lang.Math
生成器一样,ThreadLocalRandom
使用内部生成的seed
初始化,否则可能无法修改。适用时,在并发程序中使用ThreadLocalRandom
而不是共享Random
对象通常会遇到更少的开销和争用。
ThreadLocalRandom
从ThreadLocal
用法实现并发:
private static final ThreadLocal<ThreadLocalRandom> localRandom =
new ThreadLocal<ThreadLocalRandom>() {
protected ThreadLocalRandom initialValue() {
return new ThreadLocalRandom();
}
};
另一方面,Math.random()
使用限制并行性的synchronize
。来自doc:
此方法已正确同步,以允许正确使用多个 一个帖子。
以下是代码:
public static double random() {
if (randomNumberGenerator == null) initRNG();
return randomNumberGenerator.nextDouble();
}
这是synchronized
initRNG()
:
private static synchronized void initRNG() {
if (randomNumberGenerator == null)
randomNumberGenerator = new Random();
}