1.软文推荐

2.软文推荐

3.软文推荐

随机数我们应该不陌生,业务中我们用它来生成验证码,或者对重复性要求不高的id,甚至我们还用它在年会上搞抽奖。今天我们来探讨一下这个东西。如果使用不当会引发一系列问题。

随机数我们应该不陌生,业务中我们用它来生成验证码,或者对重复性要求不高的id,甚至我们还用它在年会上搞抽奖。今天我们来探讨一下这个东西。如果使用不当会引发一系列问题。

Java中的随机数

我们需要在Java中随机生成一个数字。java开发中我们通常使用java.util.Random来搞,它提供了一种伪随机的生成机制。Jvm 通过传入的种子(seed)来确定生成随机数的区间,只要种子一样,获取的随机数的序列就是一致的。而且生成的结果都是可以预测的。是一种伪随机数的实现,而不是真正的随机数。来确定使用的但是有些用例直接使用可能会导致一些意想不到的问题。Random的一个普遍用法:

// Random 实例
Random random = new Random();
//调用 nextInt() 方法 此外还有nextDouble(), nextBoolean(), nextFloat(), ...
random.nextInt();
或者,我们可以使用java中的数学计算类:
Math.random();
Math类只包含一个Random实例来生成随机数:
public static double random() {
Random rnd = randomNumberGenerator;
if (rnd == null) {
// 返回一个新的Random实例
rnd = initRNG();
}
return rnd.nextDouble();
}

java.util.Random的用法是线程安全的。但是,在不同线程上并发使用相同的Random实例可能会导致争用,从而导致性能不佳。其原因是使用所谓的种子来生成随机数。种子是一个简单的数字,它为生成新的随机数提供了基础。我们来看看Random中的next(int bits)方法:

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));}

首先,旧种子和新种子存储在两个辅助变量上。在这一点上,创造新种子的原则并不重要。要保存新种子,使用compareAndSet()方法将旧种子替换为下一个新种子,但这仅仅在旧种子对应于当前设置的种子的条件下才会触发。如果此时的值由并发线程操纵,则该方法返回false,这意味着旧值与例外值不匹配。因为是循环内进行的操作,那么会发生自旋,直到变量与例外值匹配。这可能会导致性能不佳和线程竞争。

多线程下的随机数

如果更多线程主动生成具有相同Random的实例的新随机数,则上述情况发生的概率越高。对于生成许多(非常多)随机数的程序,不建议使用这种方式。在这种情况下,您应该使用ThreadLocalRandom,它在1.7版本中添加到Java中。ThreadLocalRandom扩展了Random并添加选项以限制其使用到相应的线程实例。为此,ThreadLocalRandom的实例保存在相应线程的内部映射中,并通过调用current()来返回对应的Random。使用方式如下:

ThreadLocalRandom.current().nextInt()
安全的随机数

通过对Random的一些分析我们可以知道Random事实上是伪随机,是可以推导出规律的,而且依赖种子(seed)。如果我们搞抽奖或者其他一些对随机数敏感的场景时,用Random就不合适了,容易被人钻空子。JDK提供了SecureRandom来解决这个事情。 SecureRandom是强随机数生成器,它可以产生高强度的随机数,产生高强度的随机数依赖两个重要的因素:种子和算法。算法是可以有很多的,通常如何选择种子是非常关键的因素。 Random的种子是System.currentTimeMillis(),所以它的随机数都是可预测的, 是弱伪随机数。强伪随机数的生成思路:收集计算机的各种信息,键盘输入时间,内存使用状态,硬盘空闲空间,IO延时,进程数量,线程数量等信息,CPU时钟,来得到一个近似随机的种子,主要是达到不可预测性。说的更通俗就是,使用加密算法生成很长的一个随机种子,让你无法猜测出种子,也就无法推导出随机序列数。

总结

今天我们探讨了业务中经常使用的随机数的一些机制和一些场景下的一些陷阱,希望你在使用随机数的时候能避免这种陷阱。

本文来源:www.lxlinux.net/7925.html,若引用不当,请联系修改。

相关文章 8

1

Digital-VM:国外便宜VPS,日本/新加坡/美国大带宽VPS,1-10Gbps,月付$4起;日本服务器$80/月起 2分钟前

digital-vm近日发布了2022最新特价优惠促销活动,全场VPS云服务器、独立服务器无需优惠码即可享受最新特价优惠,国外便宜vps云服务器低至...

2

通过SaltStack批量管理文件和计划任务 4分钟前

SaltStack是一个服务器基础架构集中化管理平台,具备配置管理、远程执行、监控等功能,基于Python语言实现,结合轻量级消息队列(ZeroMQ)...

3

影响美国服务器下载速度的原因有哪些(美国关闭服务器的后果) 6分钟前

美国服务器近些年凭借配置高、价格便宜、免备案等多种原因受到许多国内站长的青睐,使用的用户也越来越多,但有部分用户发现美国服...

4

详解Linux iptraf命令 8分钟前

iptraf命令 可以实时地监视网卡流量,可以生成网络协议数据包信息、以太网信息、网络节点状态和ip校验和错误等信息,下面为大家详细讲...

5

讲解一下Lua无状态迭代器 9分钟前

无状态的迭代器是指不保留任何状态的迭代器,因此在循环中我们可以利用无状态迭代器避免创建闭包花费额外的代价。 每一次迭代,迭代...

6

腾讯云轻量应用服务器:1核1G云服务器3M128元/年起(腾讯云轻量应用服务器) 11分钟前

腾讯云轻量应用服务器价格怎么样? 腾讯轻量应用服务器分为按流量包计费套餐和按固定带宽计费套餐两种,轻量服务器套餐不同价格不同...

7

华为云学生服务器优惠套餐 云服务器一年仅99元(华为云全国大学生暑期实践) 12分钟前

华为云的云创校园计划: 华为云助力大学生创新创业其中大家关注的学生优惠套餐!一个月9元,一年99元!价格还不错!有需要的真-大学生...

8

青云互联:美国洛杉矶CN2GIA/香港安畅CN2云服务器低至19元/月;日本云主机仅35元/月起(青云 15分钟前

青云互联怎么样? 青云互联美国洛杉矶cn2GIA云服务器低至19元/月起;香港安畅cn2云服务器低至19元/月起;日本cn2云主机低至35元/月起!青云互联...