网站首页 > java教程 正文
JDK 当中的随机数生成器其实对于普通开发者来讲基本够用,不过对于一些比较复杂的场景来讲,原有的类结构对扩展并不是很友好。
这一条更新来自:JEP 356: Enhanced Pseudo-Random Number Generators,相比之下,这一条实用多了。
我们都用过随机数,不过一般情况下我们很少去认真地对待随机数的具体结果,就好像它是真的随机一样。
var random = new Random(System.currentTimeMillis());
for (int i = 0; i < 10; i++) {
System.out.println(random.nextInt());
}
除了 Random 类,JDK 当中还提供了另外几个随机数的成员:
- ThreadLocalRandom:顾名思义,提供线程间独立的随机序列。它只有一个实例,多个线程用到这个实例,也会在线程内部各自更新状态。它同时也是 Random 的子类,不过它几乎把所有 Random 的方法又实现了一遍。
- SplittableRandom:非线程安全,但可以 fork 的随机序列实现,适用于拆分子任务的场景。
ThreadLocalRandom 继承自 Random,而 SplittableRandom 与它俩则没什么实际的关系,因此如果我们在代码当中想要动态切换 Random 和 SplittableRandom 就只能定义两个成员,并且在用到的地方做判断:
Java 16
SplittableRandom splittableRandom = ...;
Random random = ...;
boolean useSplittableRandom = false;
...
if (useSplittableRandom) {
nextInt = splittableRandom.nextInt();
} else {
nextInt = random.nextInt();
}
而且如果想要自己扩展随机数的算法,也只能自己去实现,原有的定义方式缺乏一个统一的接口。
Java 17 为了解决这个问题,定义了几个接口:
这样我们就可以面向接口编程啦~
另外,尽管各个实现的细节不太一样,但思路基本上一致,因此老版本当中的几个随机数的类当中存在大量重复或者相似的代码。连 JDK 都存在 CV 代码的情况,那我们为了快速实现需求 CV 代码也不丢人,对不。
Java 17 把这些高度相似的逻辑抽了出来,搞了一个新的类:RandomSupport,又一个 3000 行的 Java 文件。
所以以前:
**Java 16 **
// Random.java
public DoubleStream doubles() {
return StreamSupport.doubleStream
(new RandomDoublesSpliterator
(this, 0L, Long.MAX_VALUE, Double.MAX_VALUE, 0.0),
false);
}
// SplittableRandom.java
public DoubleStream doubles(long streamSize, double randomNumberOrigin,
double randomNumberBound) {
if (streamSize < 0L)
throw new IllegalArgumentException(BAD_SIZE);
if (!(randomNumberOrigin < randomNumberBound))
throw new IllegalArgumentException(BAD_RANGE);
return StreamSupport.doubleStream
(new RandomDoublesSpliterator
(this, 0L, streamSize, randomNumberOrigin, randomNumberBound),
false);
}
有相似的地方吧。我们再来看看 Java 17 的实现:
Java 17
// Random.java
public DoubleStream doubles() {
return AbstractSpliteratorGenerator.doubles(this);
}
//SplittableRandom.java
private AbstractSplittableGeneratorProxy proxy;
...
public DoubleStream doubles() {
return proxy.doubles();
}
...
private class AbstractSplittableGeneratorProxy extends AbstractSplittableGenerator {
@Override
public int nextInt() {
return SplittableRandom.this.nextInt();
}
@Override
public long nextLong() {
return SplittableRandom.this.nextLong();
}
@Override
public java.util.SplittableRandom split(SplittableGenerator source) {
return new SplittableRandom(source.nextLong(), mixGamma(source.nextLong()));
}
}
而这个 AbstractSplittableGenerator 就定义在 RandomSupport.java 当中,是 RandomSupport 一个内部类。
你以为这就没了?不是的。提案的说明当中提到,提案的目标不是实现很多的随机数产生算法,不过这次还是添加了一些常见的实现,所以你会在 JDK 17 当中看到多了一个模块:
这些实现都有自己的名字,用注解标注出来,例如:
@RandomGeneratorProperties(
name = "L32X64MixRandom",
group = "LXM",
i = 64, j = 1, k = 32,
equidistribution = 1
)
public final class L32X64MixRandom extends AbstractSplittableWithBrineGenerator { ... }
我们可以通过名字来获取它们的实例:
var random = RandomGenerator.of("L32X64MixRandom");
for (int i = 0; i < 10; i++) {
System.out.println(random.nextInt());
}
好啦,关于随机数的更新又讲完啦。你不会又觉得这玩意没啥用吧。
猜你喜欢
- 2024-09-08 JavaWeb项目各种随机数主键ID的代码范例供大家参考学习
- 2024-09-08 Java中List集合有哪些特性?Java开发常见集合
- 2024-09-08 这么一篇.Java性能权威指南.不需要好好的了解一下吗?
- 2024-09-08 一篇文章彻底弄懂CAS实现SSO单点登录原理
- 2024-09-08 Java练习:输出并统计水仙花数、猜数字小游戏
- 2024-09-08 Javaweb代码创建JESESSION32位随机数及session最大不活动时间
- 2024-09-08 Java 中生成一组不重复随机整数的简便方法
- 2024-09-08 JDK 17 - Java 17 的新特性速览(java的什么特性实现了软件开发人员一次编写)
- 2024-09-08 Java教学:Integer、日期类、数字类、随机数、枚举,一次搞定!
- 2024-09-08 Java程序员面试宝典:用这100个问答搞定面试官
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)