概述

java.util.Random可以产生int、long、float、double以及Goussian等类型的随机数。这也是它与java.lang.Math中的方法Random()最大的不同之处,后者只产生double型的随机数。
该类的实例被用于生成伪随机数的流。该类使用一个 48 位的种子,它被一个线性同余公式所修改。如果 Random 的两个实例用同一种子创建,对每个实例完成同方法调用序列它们将生成和返回相同的数序列成同一方法调用序列,它们将生成和返回相同的数序列。
示例
public class RandomTest {
public static void main(String[] args) {
testRandom();
System.out.println("---------------------");
testRandom();
System.out.println("---------------------");
testRandom();
}
public static void testRandom(){
Random random = new Random(1);
for(int i=0; i<5; i++){
System.out.print(random.nextInt()+"\t");
}
System.out.println("");
}
}
输出结果:
从结果中发现,只要种子一样,获取的随机数的序列就是一致的。是一种伪随机数的实现,而不是真正的随机数。
Random 源码分析
Random 类结构
class Random implements java.io.Serializable {
private final AtomicLong seed;
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
private static final AtomicLong seedUniquifier = new AtomicLong(8682522807148012L);
有参构造方法
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
通过传入一个种子,来生成随机数,通过上面的例子发现,种子一样产生的随机数序列一样,如果每次使用想产生不一样的序列,那就只能每次传入一个不一样的种子。
无参构造方法
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
private static long seedUniquifier() {
// L'Ecuyer, "Tables of Linear Congruential Generators of
// Different Sizes and Good Lattice Structure", 1999
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
通过源码发现,无参的构造方法,里面帮我们自动产生了一个种子,并通过CAS自旋方式保证,每次获取的种子不一样,从而保证每次new Random()获取的随机序列不一致。
nextInt() 方法:获取 int 随机数
public int nextInt() {
return next(32);
}
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));
}
从代码中我们可以发现,只要种子确定后,每次产生的数,都是采用固定的算法进行产生的,所以只要种子确定后,每次产生的序列就是固定的。
每次更新种子的时候是使用的CAS来更新的,如果高并发的环境下,性能是个问题。
安全性问题
试想下,如果这是一个摇奖平台,只要种子确定后,每次产生的序列都一样。这样就可利用这个漏洞来预测下一次*的号码,这样容易被一些人钻空子。
jdk建议大家尽量要使用 SecureRandom 来实现随机数的生成。
SecureRandom
SecureRandom是强随机数生成器,主要应用的场景为:用于安全目的的数据数,例如生成秘钥或者会话标示(session ID),在上文《伪随机数安全性》中,已经给大家揭露了弱随机数生成器的安全问题,而使用SecureRandom这样的强随机数生成器将会极大的降低出问题的风险。
产生高强度的随机数,有两个重要的因素:种子和算法。算法是可以有很多的,通常如何选择种子是非常关键的因素。 如Random,它的种子是System.currentTimeMillis(),所以它的随机数都是可预测的, 是弱伪随机数。
强伪随机数的生成思路:收集计算机的各种信息,键盘输入时间,内存使用状态,硬盘空闲空间,IO延时,进程数量,线程数量等信息,CPU时钟,来得到一个近似随机的种子,主要是达到不可预测性。
说的简单点就是,使用加密算法生成很长的一个随机种子,让你无法猜测出种子,也就无法推导出随机序列数。
Random性能问题
从 Random 源码中我们发现,每次获取随机数的时候都是使用CAS的方式进行更新种子的值。这样在高并发的环境中会存在大量的CAS重试,导致性能下降。这时建议大家使用ThreadLocalRandom类来实现随机数的生成。
ThreadLocalRandom 实现原理
Thread 类
Thread 类中有一个 threadLocalRandomSeed 属性。
ThreadLocalRandom 结构
SEED 变量是 threadLocalRandomSeed 在 Thread 对象中的偏移量。
ThreadLocalRandom.nextSeed() 方法
从这个方法中,我们发现,每个线程的种子值都存储在Thread对象的threadLocalRandomSeed 属性中。
结论
因为ThreadLocalRandom 中的种子存储在Thread对象中,所以高并发获取Random对象时,不会使用CAS来保证每次获取的值不一致。
每个线程维护一个它自己的种子,每个线程需要获取随机数的时候,从当前的Thread对象中获取当前线程的种子,进行获取随机数,性能大大提高。
好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对的支持。
# java.util.random
# java
# random原理
# java.util.random包
# 浅谈java中Math.random()与java.util.random()的区别
# java.util.Random和concurrent.ThreadLocalRandom使用对比
# 随机数
# 都是
# 象中
# 来实现
# 自己的
# 是个
# 是一种
# 摇奖
# 让你
# 好了
# 那就
# 也就
# 将会
# 有很多
# 我们可以
# 这是一个
# 给大家
# 就可
# 很长
# 这篇文章
相关文章:
浅析上传头像示例及其注意事项
建站之星后台管理如何实现高效配置?
教育培训网站制作流程,请问edu教育网站的域名怎么申请?
如何在阿里云高效完成企业建站全流程?
免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?
在线教育网站制作平台,山西立德教育官网?
广东专业制作网站有哪些,广东省能源集团有限公司官网?
免费网站制作appp,免费制作app哪个平台好?
代刷网站制作软件,别人代刷火车票靠谱吗?
网站好制作吗知乎,网站开发好学吗?有什么技巧?
简单实现Android文件上传
网站制作企业,网站的banner和导航栏是指什么?
如何设置并定期更换建站之星安全管理员密码?
标准网站视频模板制作软件,现在有哪个网站的视频编辑素材最齐全的,背景音乐、音效等?
建站之星代理费用多少?最新价格详情介绍
,如何利用word制作宣传手册?
已有域名如何快速搭建专属网站?
建站之星如何取消后台验证码生成?
建站为何优先选择香港服务器?
建站之星后台密码遗忘或太弱?如何重置与强化?
网站制作需要会哪些技术,建立一个网站要花费多少?
建站之星IIS配置教程:代码生成技巧与站点搭建指南
广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?
如何通过IIS搭建网站并配置访问权限?
建站主机默认首页配置指南:核心功能与访问路径优化
如何选择CMS系统实现快速建站与SEO优化?
建站主机类型有哪些?如何正确选型
建站ABC备案流程中有哪些关键注意事项?
黑客如何利用漏洞与弱口令入侵网站服务器?
成都网站制作价格表,现在成都广电的单独网络宽带有多少的,资费是什么情况呢?
如何在阿里云虚拟主机上快速搭建个人网站?
北京制作网站的公司,北京铁路集团官方网站?
制作网站的网址是什么,请问后缀为.com和.com.cn还有.cn的这三种网站是分别是什么类型的网站?
如何通过建站之星自助学习解决操作问题?
电影网站制作价格表,那些提供免费电影的网站,他们是怎么盈利的?
python的本地网站制作,如何创建本地站点?
香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化
浙江网站制作公司有哪些,浙江栢塑信息技术有限公司定制网站做的怎么样?
韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南
婚礼视频制作网站,学习*后期制作的网站有哪些?
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
建站之星3.0如何解决常见操作问题?
如何在沈阳梯子盘古建站优化SEO排名与功能模块?
微课制作网站有哪些,微课网怎么进?
寿县云建站:智能SEO优化与多行业模板快速上线指南
如何快速生成高效建站系统源代码?
如何确保西部建站助手FTP传输的安全性?
公司门户网站制作公司有哪些,怎样使用wordpress制作一个企业网站?
家庭建站与云服务器建站,如何选择更优?
建站之星安装后如何自定义网站颜色与字体?
*请认真填写需求信息,我们会在24小时内与您取得联系。