博舍

生成随机整数方法 随机函数生成随机整数的方法

生成随机整数方法

黄色警告的意思是这个函数未来可能会被MATLAB移除,请用rand()函数,当然我们现在不熟悉rand()函数,还可以继续用这个函数。

3,生成10个-7到15之间的随机整数在主窗口中输入 randint(1,10,[-7 15]) 回车

结论:randint()函数其实是rand()函数的特殊版本,randint()能够生成的所有整数rand()函数都可以做到,不过需要我们自己去手动进行取整以及区间变换操作,randint()函数用起来方便,但是未来有可能这个函数被删除,所有希望大家也多去了解一下rand()函数。

Java中生成随机数的4种方式!

在Java中,生成随机数的场景有很多,所以本文我们就来盘点一下4种生成随机数的方式,以及它们之间的区别和每种生成方式所对应的场景。

1.Random

Random类诞生于JDK1.0,它产生的随机数是伪随机数,也就是有规则的随机数。Random使用的随机算法为linearcongruentialpseudorandomnumbergenerator(LGC)线性同余法伪随机数。在随机数生成时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的变换,从而产生需要的随机数字。

Random对象在种子数相同的情况下,相同次数生成的随机数是相同的。比如两个种子数相同的Random对象,第一次生成的随机数字完全相同,第二次生成的随机数字也完全相同。默认情况下newRandom()使用的是当前纳秒时间作为种子数的。

①基础使用

使用Random生成一个从0到10的随机数(不包含10),实现代码如下:

//生成Random对象Randomrandom=newRandom();for(inti=0;i>(48-bits));}

PS:本文所有源码来自于JDK1.8.0_211。

从以上源码可以看出,Random底层使用的是CAS(CompareandSwap,比较并替换)来解决线程安全问题的,因此对于绝大数随机数生成的场景,使用Random不乏为一种很好的选择。​

PS:Java并发机制实现原子操作有两种:一种是锁,一种是CAS。​

CAS是CompareAndSwap(比较并替换)的缩写,java.util.concurrent.atomic中的很多类,如(AtomicIntegerAtomicBooleanAtomicLong等)都使用了CAS机制来实现。

2.ThreadLocalRandom

ThreadLocalRandom是JDK1.7新提供的类,它属于JUC(java.util.concurrent)下的一员,为什么有了Random之后还会再创建一个ThreadLocalRandom?​

原因很简单,通过上面Random的源码我们可以看出,Random在生成随机数时使用的CAS来解决线程安全问题的,然而**CAS在线程竞争比较激烈的场景中效率是非常低的,原因是CAS对比时老有其他的线程在修改原来的值,所以导致CAS对比失败,所以它要一直循环来尝试进行CAS操作。所以在多线程竞争比较激烈的场景可以使用ThreadLocalRandom来解决Random执行效率比较低的问题**。​

当我们第一眼看到ThreadLocalRandom的时候,一定会联想到一次类ThreadLocal,确实如此。ThreadLocalRandom的实现原理与ThreadLocal类似,它相当于给每个线程一个自己的本地种子,从而就可以避免因多个线程竞争一个种子,而带来的额外性能开销了。

①基础使用

接下来我们使用ThreadLocalRandom来生成一个0到10的随机数(不包含10),实现代码如下:

//得到ThreadLocalRandom对象ThreadLocalRandomrandom=ThreadLocalRandom.current();for(inti=0;i>1;u+m-(r=u%bound)>>1);}returnr;}finallongnextSeed(){Threadt;longr;//readandupdateper-threadseed//获取当前线程中threadLocalRandomSeed变量,然后在种子的基础上累加GAMMA值作为新种子//再使用UNSAFE.putLong将新种子存放到当前线程的threadLocalRandomSeed变量中UNSAFE.putLong(t=Thread.currentThread(),SEED,r=UNSAFE.getLong(t,SEED)+GAMMA);returnr;}③优缺点分析

ThreadLocalRandom结合了Random和ThreadLocal类,并被隔离在当前线程中。因此它通过避免竞争操作种子数,从而在多线程运行的环境中实现了更好的性能,而且也保证了它的线程安全。

另外,不同于Random,ThreadLocalRandom明确不支持设置随机种子。它重写了Random的setSeed(longseed)方法并直接抛出了UnsupportedOperationException异常,因此降低了多个线程出现随机数重复的可能性。

源码如下:

publicvoidsetSeed(longseed){//onlyallowcallfromsuper()constructorif(initialized)thrownewUnsupportedOperationException();}

只要程序中调用了setSeed()方法就会抛出UnsupportedOperationException异常,如下图所示:

ThreadLocalRandom缺点分析

虽然ThreadLocalRandom不支持手动设置随机种子的方法,但并不代表ThreadLocalRandom就是完美的,当我们查看ThreadLocalRandom初始化随机种子的方法initialSeed()源码时发现,默认情况下它的随机种子也是以当前时间有关,源码如下:

privatestaticlonginitialSeed(){//尝试获取JVM的启动参数Stringsec=VM.getSavedProperty("java.util.secureRandomSeed");//如果启动参数设置的值为true,则参数一个随机8位的种子if(Boolean.parseBoolean(sec)){byte[]seedBytes=java.security.SecureRandom.getSeed(8);longs=(long)(seedBytes[0])&0xffL;for(inti=1;i

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。

上一篇

下一篇