java中ThreadLocalRandom的使用
java中ThreadLocalRandom的使用
在java中我们通常会需要使用到java.util.Random来便利的生产随机数。但是Random是线程安全的,如果要在线程环境中的话就有可能产生性能瓶颈。
我们以Random中常用的nextInt方法为例来具体看一下:
public int nextInt() {
return next(32);
}
nextInt方法实际上调用了下面的方法:
protected int next(int bits) {
long oldseed, nextseed;
AtomicLong seed = this.seed;
do {
oldseed = seed.get();
nextseed = (oldseed * multiplier + addend) & mask;
} while (!seed.compareAndSet(oldseed, nextseed));
return (int)(nextseed >>> (48 - bits));
}
从代码中我们可以看到,方法内部使用了AtomicLong,并调用了它的compareAndSet方法来保证线程安全性。所以这个是一个线程安全的方法。
其实在多个线程环境中,Random根本就需要共享实例,那么该怎么处理呢?
在JDK 7 中引入了一个ThreadLocalRandom的类。ThreadLocal大家都知道就是线程的本地变量,而ThreadLocalRandom就是线程本地的Random。
我们看下怎么调用:
ThreadLocalRandom.current().nextInt();
我们来为这两个类分别写一个benchMark测试:
public class RandomUsage {
public void testRandom() throws InterruptedException {
ExecutorService executorService=Executors.newFixedThreadPool(2);
Random random = new Random();
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
callables.add(() -> {
return random.nextInt();
});
}
executorService.invokeAll(callables);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(RandomUsage.class.getSimpleName())
// 预热5轮
.warmupIterations(5)
// 度量10轮
.measurementIterations(10)
.forks(1)
.build();
new Runner(opt).run();
}
}
public class ThreadLocalRandomUsage {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.MICROSECONDS)
public void testThreadLocalRandom() throws InterruptedException {
ExecutorService executorService=Executors.newFixedThreadPool(2);
List<Callable<Integer>> callables = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
callables.add(() -> {
return ThreadLocalRandom.current().nextInt();
});
}
executorService.invokeAll(callables);
}
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(ThreadLocalRandomUsage.class.getSimpleName())
// 预热5轮
.warmupIterations(5)
// 度量10轮
.measurementIterations(10)
.forks(1)
.build();
new Runner(opt).run();
}
}
分析运行结果,我们可以看出ThreadLocalRandom在多线程环境中会比Random要快。
本文的例子可以参考https://github.com/ddean2009/learn-java-concurrency/tree/master/ThreadLocalRandom
更新文章请参考flydean的博客
java中ThreadLocalRandom的使用的更多相关文章
- java中ThreadLocalRandom类和Random类的使用
package frank; import java.lang.*; import java.util.*;//工具类一般都在util里面 import java.util.concurrent.Th ...
- Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom
Java中的随机数生成器:Random,ThreadLocalRandom,SecureRandom 文中的 Random即:java.util.Random,ThreadLocalRandom 即: ...
- java中多线程中Runnable接口和Thread类介绍
java中的线程时通过调用操作系统底层的线程来实现线程的功能的. 先看如下代码,并写出输出结果. // 请问输出结果是什么? public static void main(String[] args ...
- Java中基础类库使用
Java中基础类库: 在这里我仅仅介绍几种我个人觉得会常常使用的 1:Object类中的Clone机制仅仅是对对象进行浅层次的克隆,假设须要进行深层次的克隆的话那么就要自己写(详细Clone方法请參考 ...
- 沉淀再出发:java中的HashMap、ConcurrentHashMap和Hashtable的认识
沉淀再出发:java中的HashMap.ConcurrentHashMap和Hashtable的认识 一.前言 很多知识在学习或者使用了之后总是会忘记的,但是如果把这些只是背后的原理理解了,并且记忆下 ...
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- java中的字符串相关知识整理
字符串为什么这么重要 写了多年java的开发应该对String不陌生,但是我却越发觉得它陌生.每学一门编程语言就会与字符串这个关键词打不少交道.看来它真的很重要. 字符串就是一系列的字符组合的串,如果 ...
- Java中的Socket的用法
Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...
- java中Action层、Service层和Dao层的功能区分
Action/Service/DAO简介: Action是管理业务(Service)调度和管理跳转的. Service是管理具体的功能的. Action只负责管理,而Service负责实施. DAO只 ...
随机推荐
- Apache本地服务器搭建(Mac版)
由于Mac自带apache服务器,所以无需下载,apache默认处于开启状态. 可以在浏览器输入localhost,显示It works!,代表目前处于开启状态,默认文件目录为/Library/Web ...
- CentOS-7.6 下搭建 NIS 服务器
##服务端配置: ####Server: 192.168.0.178(CentOS 7.6) # systemctl stop firewalld # systemctl disable firewa ...
- implements Serializable
implements Serializable 1. 序列化和反序列化 序列化: 把对象转换为字节序列的过程称为对象的序列化. 反序列化: 把字节序列恢复为对象的过程称为对象的反序列化. 在Java和 ...
- Netty:Channel
上一篇我们通过一个简单的Netty代码了解到了Netty中的核心组件,这一篇我们将围绕核心组件中的Channel来展开学习. Channel的简介 Channel代表着与网络套接字或者能够进行IO操作 ...
- 001_manifest.json手册
manifest.json 是一个 JSON 格式的文件,是每个 WebExtension必须包含的唯一文件. 使用manifest.json,您可以指定扩展名的基本元数据,如名称和版本,还可以指定扩 ...
- 分享一下,PHP实现第四方QQ微信扫码登陆,不接入qq互联以及微信开发者平台就可以实现用户对接鹅厂,phpQQ微信扫码登陆
自己抓的QQ包以及整合了网上一些已经封装好了的代码具体如下:QQ: <?php class QQ extends Curl_Api { //获取登录验证码 public function QRc ...
- 直播 | Apache Kylin & Apache Hudi Meetup
千呼万唤始出来,Meetup 直播终于来啦- 本次线上 Meetup 由 Apache Kylin 与 Apache Hudi 社区联合举办,将于 3 月 14 日晚进行直播,邀请到来自丁香园.腾讯. ...
- LeetCode 题解 | 242. 有效的字母异位词
给定两个字符串 s 和t,编写一个函数来判断 t 是否是 s 的字母异位词. 示例 1: 输入: s = "anagram", t = "nagaram" 输出 ...
- C语言 文件操作(二)
1.fputc(); fputc 是 file output char 的所以,意思是向指定的文件中写入一个字符.fputc() 的用法为: int fputc ( int ch, FILE *fp ...
- 数据结构和算法(Golang实现)(9)基础知识-算法复杂度及渐进符号
算法复杂度及渐进符号 一.算法复杂度 首先每个程序运行过程中,都要占用一定的计算机资源,比如内存,磁盘等,这些是空间,计算过程中需要判断,循环执行某些逻辑,周而反复,这些是时间. 那么一个算法有多好, ...