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