1. 前面都是查找过程,可以直接看总结
看完总结再看查找过程可以更好的理解查找过程。
本文产生的原因是因为在学习linux和redis的过程中对随机数的产生有了兴趣,所以查看了java的源码。
新人博客,如果有误,希望大佬指正
2. value的产生(AtomicLong)
3. Random中的seedUniquifier(种子唯一标识符)
这里是获得了一个AtomicLong的对象其中new AtomicLong(long xxx);是给AtomicLong中的value属性赋值
4. 获得long属性的seedUniquifier
a. 获得current通过seedUniquifier.get()
return的时value,也就是第二步中赋值的8682522807148012L
b. 获得next将current与181783497276652981L相乘
c. 判断
ⅰ. 如何获取Unsafe
这一步关键是else,他的目的就是返回一个Unsafe对象theUnsafe
ⅱ. unsafe对象获取的流程,类似于工厂模式
回到AtomicLong给他的unsafe属性赋值
ⅲ. 获得unsafe对象,以用来调用compareAndSwapLong
在获得一个unsafe对象后调用compareANdSwapLong方法
this为自身对象
value0ffset是AtomicLong中的一个常量,值应该是默认的0
expect为current
update为next
ⅳ. 进入比较方法后发现这个是一个boolean值
由此可以推断compareAndSet(current, next)是获得了一个boolean值,通过这个boolean来判断是否可以返回next,由于这个源码不可看,所以无法得知原理
但是可以直到这个方法是CAS的
5. 再次回到Random对象的创建
到这一步基本就可以大概知道random创建了什么,this(seedUniquifier() ^ System.nanoTime)
seedUniquifier是获得的next,通过源码可以发现他是一个固定的值也就是8682522807148012L * 181783497276652981L;
nanoTime是一个时间戳
6. 继续往前回溯,得到math中所获得的Random对象randomNumberGenerator
7. 继续回溯发现math中调用的random是通过一个Random对象调用nextDouble()获得的
8. nextDouble()的计算过程
9. RandomNumberGeneratorHolder
他是math中创建的内部类
10. 总结math中的Random实现的原理
a. 获得random对象并且进行nextDouble()的运算
return RandomNumberGeneratorHolder.randomNumberGenerator.nextDouble();
b. random对象的创建
public Random() { this(seedUniquifier() ^ System.nanoTime()); }
c. seedUniquifier的获取:其实就是两个数相乘
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; } }