【问题标题】:How does ThreadLocalRandom results in less Contention?ThreadLocalRandom 如何减少争用?
【发布时间】:2013-10-21 17:56:39
【问题描述】:

正在浏览 Java 7 的新特性,发现添加了这个新类:

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

正在研究如何实现,从而减少争用并提高性能。

【问题讨论】:

  • Math.random()synchronized。源代码在您的 JDK 安装中可用。
  • 完全是猜测,但我敢打赌Math.random() 必须同步以确保两个线程不会获得相同的随机数。 ThreadLocalRandom,顾名思义,不必同步。
  • @SotiriosDelimanolis - Math.random() 不是synchronized 而是randomNumberGenerator 初始化方法initRNGsynchronized

标签: java


【解决方案1】:

实际上,两者的区别在于同步。 Math#random() 可能被多个线程同时调用,因此必须进行同步,而 ThreadLocalRandomRandom 的非同步版本,它是线程绑定的,这意味着每个线程都有自己的(更快的)分配。

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

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

【讨论】:

  • 感谢您的回答,只是想知道一件事,现在如果我们每个线程都有 RandomNumberGenerator,它将对伪随机数生成产生什么影响??
  • @SachinThapa 据我了解,这两种方法都提供了同等程度的随机性。
【解决方案2】:

来自 java 文档:

ThreadLocalRandom 是一个与当前线程隔离的随机数生成器。与java.lang.Math 类使用的全局java.util.Random 生成器一样,ThreadLocalRandom 使用内部生成的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();
     }

【讨论】:

  • initRNG() 在 JVM 的整个生命周期中只会被调用一次。你要找的东西有点难以解释:)
  • 这也是第一次增加成本。
  • 感谢您的回复,那么就“数字有多随机?”而言,每个线程都有一个 RandomNumberGenerator 会有什么不同?
猜你喜欢
  • 1970-01-01
  • 2023-02-02
  • 2017-02-11
  • 2021-12-21
  • 2019-09-21
  • 1970-01-01
  • 2015-11-26
  • 2021-04-25
  • 1970-01-01
相关资源
最近更新 更多