秒懂 Java ThreadLocalRandom
admin
2024-05-13 18:23:42
0

随机数生成是一个非常常见的操作,而且 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 生成随机 int、long 和 double 值。

使用 ThreadLocalRandom 生成随机数

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

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

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

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

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

int boundedRandomValue = ThreadLocalRandom.current().nextInt(0, 100);

请注意,这是一个左闭右开区间,也就是说,上面的实例生成的随机数在 [0,100) 之间,包含了 0 但不包含 100。

同样的,我们可以通过调用 nextLong() 和 nextDouble() 方法生成 long 和 double 类型的随机值,调用方式与上面示例中 nextInt() 类似。

Java 8 还添加了 nextGaussian() 方法从生成器序列中生成下一个正态分布的值,其值范围在 0.0 和 1.0 之间。

与Random 方法类似,ThreadLocalRandom 也提供了 doubles() 、ints() 和 longs() 方法生成一序列流式 ( stream ) 的随机值。

使用 JMH 比较 ThreadLocalRandom 和 Random

记下来,我们看看如何在多线程环境中分别使用这两个类生成随机值,然后再使用 JMH 比较它们的性能。

首先,我们创建一个示例,其中所有线程共享一个 Random 实例。

ExecutorService executor = Executors.newWorkStealingPool();
List> callables = new ArrayList<>();
Random random = new Random();
for (int i = 0; i < 1000; i++) {callables.add(() -> {return random.nextInt();});
}
executor.invokeAll(callables);

上面的代码中,我们把使用 Random 实例生成随机值的任务提交给 ExecutorService 。

然后,我们使用 JMH 基准测试来检查上面代码的性能

# Run complete. Total time: 00:00:36
Benchmark                                            Mode Cnt Score    Error    Units
ThreadLocalRandomBenchMarker.randomValuesUsingRandom avgt 20  771.613 ± 222.220 us/op

接着,类似地,我们使用 ThreadLocalRandom 而不是 Random 实例

ExecutorService executor = Executors.newWorkStealingPool();
List> callables = new ArrayList<>();
for (int i = 0; i < 1000; i++) {callables.add(() -> {return ThreadLocalRandom.current().nextInt();});
}
executor.invokeAll(callables);

上面的代码,为线程池中的每个线程单独使用了一个 ThreadLocalRandom 实例。

下面是使用 JMH 对 ThreadLocalRandom 的测试结果

# Run complete. Total time: 00:00:36
Benchmark                                                       Mode Cnt Score    Error   Units
ThreadLocalRandomBenchMarker.randomValuesUsingThreadLocalRandom avgt 20  624.911 ± 113.268 us/op

通过JMH 的测试结果中可以看出,使用 Random 生成 1000 个随机值所花费的平均时间是 772 微秒,但使用 ThreadLocalRandom 只花了 625 微秒。嗯,差距不是很大,但好歹也是有差距的,因为生成 1000 个随机数是瞬间的事情。

因此,我们可以得出结论,ThreadLocalRandom 在高度并发的环境中更有效。

相关内容

热门资讯

对高一孩子的寄语和鼓励的话怎么... 对高一孩子的寄语和鼓励的话怎么写1. 用自己的不懈努力,证明你一点儿也不比别人差。2. 在逆境或困难...
老照片用什么词语形容? 老照片用什么词语形容?南宁市几尼手工艺品店贵港市港北区几尼广告工作室
节拍器60的速度怎么调 节拍器60的速度怎么调摆杆上游码可上下调动,以调整速度,并和面板上的刻度相对照。节拍器60的速度不是...
请你写信告诉我关于你上午的情况... 请你写信告诉我关于你上午的情况(译成英文)Please send me a letter about...
求秋夜雨寒作品集 求秋夜雨寒作品集《说你爱我》 《许我一生还你一世》《与爱情为邻》 《终难忘》 《相遇》 《若爱只是擦...
喘息声是什么意思? 喘息声是什么意思?呼吸时产生的声音
别小齐的表哥是谁? 别小齐的表哥是谁?别小气的表哥应该是很大气,正好跟他相反的意思。
我是大女儿,与我弟弟相差12岁... 我是大女儿,与我弟弟相差12岁,父母偏爱他吧很正常。一定要想开。你也应该和父母一起疼爱他。但是,绝对...
为什么网上很多都说周杰伦不如刘... 为什么网上很多都说周杰伦不如刘德华?就因为刘德华是长辈吗?刘德华只不过是过时的明星而已公正的说,写歌...
“诺颜”和“莫离”哪一个笔名好... “诺颜”和“莫离”哪一个笔名好听?请陈述理由。要看写作风格,(虽然两个都挺玛丽苏的),走甜美校园洛丽...
明星真人秀真的有剧本么? 明星真人秀真的有剧本么?我觉得明星真人秀确实是有剧本的,因为只有剧本才能够表现的这么流畅,这么的有话...
求钢之炼金术师每集预告后的一句... 求钢之炼金术师每集预告后的一句话.在fa里每集看完后后.预告里都有个大叔在说话.在说完下一集标题后都...
极品飞车9音乐补丁放在什么位置 极品飞车9音乐补丁放在什么位置在你的安装目录,program files/你安装的极品飞车9位置(英...
男生汗毛重是怎么回事? 男生汗毛重是怎么回事?男性汗毛多是正常的表现,一般与雄激素有密切关系。雄激素是促进机体汗毛生长的,男...
对爱情太理想化,我错了吗? 对爱情太理想化,我错了吗?你很清楚自己对爱情的期待太过理想化,只是苦于无法改变,也无法放弃,这种矛盾...
貌似天仙和貌若天仙的,意思都是... 貌似天仙和貌若天仙的,意思都是指女子长的像天仙一样漂亮是吗?是的,比方说,某某某貌若天仙,或是貌若天...
在书店看到了一本书,是紫色壳子... 在书店看到了一本书,是紫色壳子的上面有白色的花,是一本古言,放在醉玲珑旁边的,但是我忘记看名字了在书...
给小孩报兴趣班有用吗? 给小孩报兴趣班有用吗?小孩儿把兴趣班,当然有用,但是这个用处有多少,就是你当别人的,也不动,小朋友,...
我国古代关于准备的故事 我国古代关于准备的故事我国古代关于准备的故事有一个人,在某天晚上碰到了一个神仙。神仙告诉他,有大事要...
孟买酒店女孩为什么逃走 孟买酒店女孩为什么逃走《孟买酒店》女孩逃走,是为了后面的情节发展,利于剧情的展开。因为如果不是这样,...