当前位置:网站首页>Detailed explanation of random number generated by random class
Detailed explanation of random number generated by random class
2022-07-28 08:02:00 【The galloping snail has been occupied】
Have a look first Random Construction method of
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
stay Random Class , The construction methods are 2 individual :
- One belt long Type parameter ,
- One without parameters ; In fact, it calls the construction with parameters ; If there are no parameters ,Random A default parameter will be set seed;
1.Random set default seed
First study Random How to set the default seed;
public Random() {
this(seedUniquifier() ^ System.nanoTime());
}
It is divided into 2 part :
- seedUniquifier()
- System.nanoTime(): Get system time ( nanosecond 1ns = 10-6ms)
1.1seedUniquifier Source code :
private static long seedUniquifier() {
for (;;) {
long current = seedUniquifier.get();
long next = current * 181783497276652981L;
if (seedUniquifier.compareAndSet(current, next))
return next;
}
}
private static final AtomicLong seedUniquifier
= new AtomicLong(8682522807148012L);
Code process :
- Get one Random fixed long value current ;
- utilize current To calculate the next
- utilize CAS modify seedUniquifier Value , If the modification is successful, it will return ; Because of the use of CAS So this seedUniquifier It's thread safe , It can be used in multithreading ;
To sum up : utilize random A fixed attribute value of , By multiplying by a number ( Fixed value ), Calculated a value Then return ; It can be seen that these are fixed values ; in other words , As long as the initial state is determined , The sequence of numbers generated by this function is also determined ;
1.2 Generate seed
We know the default seed: By way :seedUniquifier() Generate the number and the current time of the system 2 Numbers pass XOR bit operation Generated ; Among them, the method :seedUniquifier() What is generated is a fixed number sequence ; What changes is the system time obtained , Through this 2 Do a bit operation to generate a new number , As a starting point random The starting value of seed; So every time I call Random The nonparametric construction of a class can get a different seed It still looks more like random ;
2.Random Initialization treatment seed
We mentioned above that you can customize seed Or the system automatically generates ; stay random Get the parameters seed In fact, it was handled later , It's not going to come in seed Save directly ;
public Random(long seed) {
if (getClass() == Random.class)
this.seed = new AtomicLong(initialScramble(seed));
else {
// subclass might have overriden setSeed
this.seed = new AtomicLong();
setSeed(seed);
}
}
private static long initialScramble(long seed) {
return (seed ^ multiplier) & mask;
}
private static final long multiplier = 0x5DEECE66DL;
private static final long mask = (1L << 48) - 1;
Processing seed When , First of all, I judged whether it was Random Subclasses of , If it is Random Subclass , Then deal with it seed The method of may be rewritten , This is the time seed It will be handed over to subclasses ; If the subclass is not overridden , That's still used Random Processing methods of :initialScramble();
stay initialScramble() In dealing with seed: (seed ^ multiplier) & mask The generated value is used as Random The real initial value of seed;
3.next(int bit) Generate random number
The method is random Compare the core Methods , This method is used directly or indirectly to obtain random numbers of different types of values ;
private final AtomicLong seed;
private static final long multiplier = 0x5DEECE66DL;
private static final long addend = 0xBL;
private static final long mask = (1L << 48) - 1;
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));
}
- Get old value :oldseed
- Utilize old values oldseed , Calculate a new value nextseed ;(oldseed * multiplier + addend) & mask;
- take nextseed Update to the new value , Update successfully ended the cycle ; return (nextseed >>> (48 - bits))
The algorithm itself is not difficult , Is to use a fixed Algorithm : (oldseed * multiplier + addend) & mask; among :multiplier ,addend,mask It's all fixed values , and oldseed Is also generating random Object has been initialized , After these figures are confirmed , All the digital sequences generated by this algorithm are also determined , therefore random This algorithm is called pseudorandom ; Because after the initial value is determined , The return value obtained each time has been determined , The generated numbers are all predictable ;
4.Random Tests that generate random numbers
test 1: The transfer parameter specifies the same seed
We know through the above analysis , When the initial value seed Phase at the same time , The generated random number sequence is the same ; We can specify the same through the construction with parameters seed;
- Test code :2 individual Random, All specify the same seed:1;
long multiplier = 0x5DEECE66DL;//Random Medium multiplier
long mask =(1L << 48) - 1;//Random Medium mask
long seed = (1 ^ multiplier) & mask;// initialization seed The algorithm of
System.out.println(" from 1 The real initial generation seed:"+seed);
System.out.println("**************************");
Random r1 = new Random(1);
Random r2 = new Random(1);
for (int i = 0; i < 5; i++) {
System.out.println("[r1]"+r1.nextInt());
System.out.println("[r2]"+r2.nextInt());
System.out.println("++++++++++++++++++++++++++++++++");
}
- test result
from 1 The real initial generation seed:25214903916
**************************
[r1]-1155869325
[r2]-1155869325
++++++++++++++++++++++++++++++++
[r1]431529176
[r2]431529176
++++++++++++++++++++++++++++++++
[r1]1761283695
[r2]1761283695
++++++++++++++++++++++++++++++++
[r1]1749940626
[r2]1749940626
++++++++++++++++++++++++++++++++
[r1]892128508
[r2]892128508
++++++++++++++++++++++++++++++++
test 2: Do not pass reference Random Automatically generate initial seed
Because of the call Random The time of object construction method is different , It will lead to different system time obtained ; In this case, the initial seed It will be different ; The generated random number sequence is also different ;
- Test code (1)
Random r1 = new Random();
Random r2 = new Random();
for (int i = 0; i < 3; i++) {
System.out.println("[r1]"+r1.nextInt());
System.out.println("[r2]"+r2.nextInt());
System.out.println("++++++++++++++++++++++++++++++++");
}
- test result (1)
[r1]1283182367
[r2]-1068120877
++++++++++++++++++++++++++++++++
[r1]-816566372
[r2]735383144
++++++++++++++++++++++++++++++++
[r1]-2110975477
[r2]1838318920
++++++++++++++++++++++++++++++++
- Test code (2)
2 individual Random Use in multithreading
new Thread(() ->{
Random r1 = new Random();
System.out.println("[r1:nanoTime]"+System.nanoTime());
for (int i = 0; i < 3; i++) {
System.out.println("[r1]"+r1.nextInt());
}
}).start();
new Thread(() ->{
Random r2 = new Random();
System.out.println("[r2:nanoTime]"+System.nanoTime());
for (int i = 0; i < 3; i++) {
System.out.println("[r2]"+r2.nextInt());
}
}).start();
- test result
Tested several times ,2 individual Random Objects failed to get the same system time ; So the results are different ; But it must be pointed out that , Use in a multithreaded environment 2 One or more different Random The sequence of pseudo-random numbers generated by the object may be the same ; If you want to ensure that in a multithreaded environment , The random number sequence generated by each thread is the same , Just use the construction method of the specified parameters , Specify the same parameters ;
[r1:nanoTime]3745251056800
[r1]2110737154
[r1]-360918307
[r1]-779547580
[r2:nanoTime]3745251443500
[r2]55610651
[r2]503726359
[r2]36689994
边栏推荐
- Oracle local network service
- DNA modified noble metal nanoparticles | DNA deoxyribonucleic acid modified metal palladium Pd nanoparticles pdnps DNA
- 谈谈DOM0,DOM1,DOM2,DOM3
- Huawei Senior Engineer -- BGP routing filtering and community attributes
- Freezing and thawing of pytoch
- Parse tree structure JS
- In the task manager, the CPU speed displayed is greater than its maximum speed [main frequency]
- 【13】 Adder: how to build a circuit like Lego (Part 1)?
- What is the root cause of EMC's problems?
- Talk about row storage and column storage of database
猜你喜欢
![[Google] solve the problem that Google browser does not pop up the account and password save box and cannot save login information](/img/b3/2592e941f5d8f3505fb9763e8947a6.png)
[Google] solve the problem that Google browser does not pop up the account and password save box and cannot save login information

近红外二区AgzS量子点包裹脱氧核糖核酸DNA|DNA-AgzSQDs(齐岳)

protobuf 基本语法总结

JUC atomic class: CAS, unsafe, CAS shortcomings, how to solve ABA problems in detail

Copper indium sulfide CuInSe2 quantum dots modified DNA (deoxyribonucleic acid) DNA cuinse2qds (Qiyue)

Some experience of gd32 using Hal Library of ST and Gd official library

解析树形结构 js

The first common node of two linked lists -- two questions per day

win系统添加打印机

DNA脱氧核糖核酸修饰金属铂纳米颗粒PtNPS-DNA|科研试剂
随机推荐
Google and Stanford jointly issued a document: why do we have to use large models?
What if the computer file cannot be deleted?
EMC's "don't come back until you rectify"
记录一次mycat连接Communications link failure问题解决
任务管理器中,显示的CPU速度大于它的最大速度【主频】
滴滴SQL面试题之打车业务问题如何分析
非关系型数据库之Redis【Jedis客户端+Jedis连接集群】
非关系型数据库之Redis【redis安装】
In the task manager, the CPU speed displayed is greater than its maximum speed [main frequency]
演讲笔记 适合所有人的实用程序生成 PCG
Chapter 01 introduction of [notes of Huashu]
Industry standards and certification of common electronic products
These mobile security browsers are more than a little easy to use
DNA-CuInSeQDs近红外CuInSe量子点包裹脱氧核糖核酸DNA
awk从入门到入土(16)awk变量类型探讨--关于数字和string两种类型
Modify the conf file through sed
基于单例模式的yaml参数配置
对spark算子aggregateByKey的理解
细说共模干扰和差模干扰
Mysql, how many columns can be used to create an index?