当前位置:网站首页>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
边栏推荐
- Flowable workflow all business concepts
- Synthesis of dna-ag2sqds DNA modified silver sulfide Ag2S quantum dots
- How do we run batch mode in MySQL?
- Mysql中有哪些不同的表格?
- Lecture notes a utility for everyone to generate PCG
- js卡片层叠样式的图片切换js特效
- 聊一聊数据库的行存与列存
- Huawei Senior Engineer -- BGP routing filtering and community attributes
- DNA修饰贵金属纳米颗粒|DNA脱氧核糖核酸修饰金属钯Pd纳米颗粒PdNPS-DNA
- Industry standards and certification of common electronic products
猜你喜欢

Delete the nodes in the linked list - daily question

EMC rectification ideas

DNA修饰贵金属纳米颗粒|DNA脱氧核糖核酸修饰金属钯Pd纳米颗粒PdNPS-DNA

Talk about row storage and column storage of database

辨析覆盖索引/索引覆盖/三星索引

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

Forward propagation of deep learning neural networks (1)

MPLS --- 多协议标签交换技术

Collection | combined with my personal experience, I have summarized these seven EMC related knowledge

Clion debugging redis6 source code
随机推荐
DNA modified rhodium RH nanoparticles rhnps DNA (DNA modified noble metal nanoparticles)
对spark算子aggregateByKey的理解
Swm32 series tutorial 5-adc application
How do we run batch mode in MySQL?
Daily question - split equal sum subset
细说共模干扰和差模干扰
Chapter 01 introduction of [notes of Huashu]
登录模式:单一服务器模式、单点登录、token模式
@The role of documented
MySQL: what is the difference between like and regexp operations?
使用FFmpeg来批量生成单图+单音频的一图流视频
What if the computer file cannot be deleted?
【花书笔记】 之 Chapter01 引言
Autodesk desktop licensing service error 1067 handling method
EMC中的基石-电磁兼容滤波知识大全!
0727~ sorting out interview questions
Analysis of collector principle
DNA修饰金属锇Os纳米颗粒OsNPS-DNA|DNA修饰金属铱纳米颗粒IrNPS-DNA
The cornerstone of EMC - complete knowledge of electromagnetic compatibility filtering!
In the task manager, the CPU speed displayed is greater than its maximum speed [main frequency]