ThreadLocalRandom如何减少争用?

时间:2013-10-21 17:56:40

标签: java

正在阅读Java 7的新功能,并发现这个新类已添加:

  

对于并发访问,使用ThreadLocalRandom代替   Math.random()会减少争用,最终会更好   性能

正在研究如何实施这项工作,从而减少争用和提高绩效。

2 个答案:

答案 0 :(得分:3)

实际上,两者之间的区别在于同步。 Math#random()可以由多个线程同时调用,因此必须同步,而ThreadLocalRandomRandom的非同步版本,它是线程绑定意味着每个线程获得自己的(更快)分配。

如果仔细查看实现,您会发现Math#random()使用java.util.Random的单个实例生成随机数,其中ThreadLocalRandom为每个线程分配一个实例从这个意义上消除了争论。

ThreadLocalRandom实现并发Math#random()实现同步

答案 1 :(得分:0)

来自java DOCS:

ThreadLocalRandom是与当前线程隔离的随机数生成器。与java.util.Random类使用的全局java.lang.Math生成器一样,ThreadLocalRandom使用内部生成的seed初始化,否则可能无法修改。适用时,在并发程序中使用ThreadLocalRandom而不是共享Random对象通常会遇到更少的开销和争用。

ThreadLocalRandomThreadLocal用法实现并发:

    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();
     }