跳到主要内容

十六、Java并发 Java ThreadLocalRandom

随机数生成是一个非常常见的操作,而且 Java 也提供了 java.util.Random 类用于生成随机数,而且呢,这个类也是线程安全的,就是有一点不好,在多线程下,它的性能不佳。

为什么多线程下,Random 的性能不佳?

因为,它采用了多个线程共享一个 Random 实例。这样就会导致多个线程争用。

为了解决这个问题,Java 7 引入了 java.util.concurrent.ThreadLocalRandom 类,用于在多线程环境中生成随机数。

本文接下来的部分,就来看看如何 ThreadLocalRandom 如何执行以及如何在实际应用程序中使用它。

ThreadLocalRandom Via Random

ThreadLocalRandom 是 ThreadLocal 类和 Random 类的组合,它与当前线程隔离,通过简单地避免对 Random 对象的任何并发访问,在多线程环境中实现了更好的性能。

也就是说,相比于 java.util.Random 类全局的提供随机数生成, 使用 ThreadLocalRandom,一个线程获得的随机数不受另一个线程的影响。

另一个与 Random 类不同的是,ThreadLocalRandom 不支持显式设置种子。因为它重写了从 Random 继承的 setSeed(long seed) 方法,会在调用时始终抛出 UnsupportedOperationException

接下来我们看看如何使用 ThreadLocalRandom 生成随机 intlongdouble 值。

使用 ThreadLocalRandom 生成随机数

根据Oracle 文档,我们只需要调用 ThreadLocalRandom.current() 方法,就能返回当前线程的 ThreadLocalRandom 实例。然后,我们可以通过实例的相关方法来生成随机值。

比如下面的代码,生成一个没有任何边界的随机 int 值

int unboundedRandomValue = ThreadLocalRandom.current().nextInt());

> 其实是有边界的,它的边界就是 int 的边界。

接下来,我们看看如何生成有边界的随机 int 值,这意味着我们需要传递边界下限和边界上限作为参数