总说Random可以随机产生数值,其实是“假”的
怎么个假法?
for (int i = 0; i < 10; i++) {
Random random = new Random(15);
System.out.println(random.nextInt(100));
}
运行出来都是41,为啥呢?
随机数其实是由Random里面seed种子决定的,然后通过一个算法计算出这个所谓的随机数,其实就不是上面随机数
那么随机数是怎么产生的呢?
/**
* Creates a new random number generator. This constructor sets
* the seed of the random number generator to a value very likely
* to be distinct from any other invocation of this constructor.
*/
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
在这里创建不同的种子,所以产生不同的数,给别人幻觉是随机的。
下一个新种子是通过CAS进行更新的,如果拿到的种子和oldseed一样的话,根据算法来更新成newseed。如果拿到的种子和旧种子不一致的时候,表示已经被更新了,会循环去获取。第二次获取的时候得到新的 种子和旧的种子一样,那么也根据算法去更新种子。
在多线程操作的时候,难免会出现多个线程去操作同一个种子,比如共享对象Random random = new Random(15);通过nextInt获取下一个种子。如果有多个线程并发修改种子,那么肯定会出现CAS锁自旋,导致cpu消耗很高。
可以使用ThreadLocalRandom
它的种子和线程挂钩,所以就不会出现nextseed永远是同一个,避免使用CAS来同步,以及种子的竞争