
In the previous article , We have a deep understanding of Java Memory model , got it Java The significance of the memory model , And the problems to be solved . Finally we know :Java The memory model defines 8 Basic operations and 8 A rule , Just follow these rules for concurrent operations , Then they are safe .
Even those who are stronger than brother Shu , Look at this 16 This rule is also a headache . They are too cumbersome , It is very disadvantageous to our daily code writing . To help programmers understand , Therefore, there is the judgment principle of equal price —— Antecedent principle , It can be used to determine whether an access is safe in a concurrent environment .
Come here , We need to understand :happens-before The principle is to Java Simplification of memory model , Let's better write concurrent code . It's like Java Language and other high-level languages , For assembly language 、 Machine language and other low-level languages , It can protect programmers from 「 The pain of flesh and skin 」.
What is? happens-before?
happens-before refer to Java The sequential relationship between the two operations in the memory model . For example, operation A Prior to operation B, That is to say, operation A It happens in the operation B Before , operation A The impact can be manipulated B The observed . there 「 influence 」 Include : Values of shared variables in memory 、 Sent a message 、 Method called, etc .
Take a very simple example : In the following code i=1 In a thread A In the implementation of , and j=i In a thread B In the implementation of . because i=1 Operation precedes j=i perform , that i=1 The result of the operation should be able to be processed by the thread B The observed .
// In a thread A In the implementation of
i = 1;
// In a thread B In the implementation of
j = i;
Java There are... Under the memory model 8 strip happens-before The rules , If the operation between threads cannot be derived from the following rules , Then there is no sequential guarantee for their operation , Virtual machines or operating systems can be reordered at will , Thus, concurrent security problems may occur .
- Program Order Rule (Program Order Rule): In a thread , In order of program code , The operation of writing before takes place before the operation of writing after . To be exact , It should be the order of the control flow, not the sequence of the program code , Because we need to think about branches 、 Circulation and other structures .
- Tube lock rule (Monitor Lock Rule): One unlock The operation occurs first of all on the same lock lock operation . The same lock must be emphasized here , and “ Back ” The order of time .
- volatile Variable rule (Volatile Variable Rule): To a volatile The write operation of the variable first occurs after the read operation of the variable , there “ Back ” It also refers to the chronological order .
- Thread start rule (Thread Start Rule):Thread Object's start() Method occurs first in every action of this thread .
- Thread termination rule (Thread Termination Rule): All operations in a thread occur first at the termination detection of this thread , We can go through Thread.join() Method end 、Thread.isAlive() The thread has been terminated .
- Thread interrupt rule (Thread Interruption Rule): For threads interrupt() Method calls occur first when the interrupted thread's code detects the occurrence of an interrupt event , Can pass Thread.interrupted() Method detects if an interrupt has occurred .
- Object termination rule (Finalizer Rule): Initialization of an object completed ( End of constructor execution ) What happened first finalize() The beginning of the method .
- Transitivity (Transitivity): If you operate A First occurs in operation B, operation B First occurs in operation C, Then we can get the operation A First occurs in operation C Conclusion .
Minimalist practice cases
Java The language does not need any synchronization means to guarantee , The antecedent occurrence rule that can be established , That's all . The following is an example to illustrate how to use these rules to determine whether the operations are sequential , Is it thread safe .
private int value = 0;
public void setValue(int value){
this.value = value;
}
public int getValue(){
return value;
}
The above code is a set of very common getter/setter Method . Assuming that thread A and B, Threads A First ( The order of time ) Called setValue(1), After that thread B Calling... Of the same object getValue(), So thread B What is the return value received ?
Let's analyze the rules of antecedent principle in turn :
- First , Because the two methods are separated by threads A And thread B call , Not in a thread , So the procedural order rule doesn't apply here .
- next , Because there is no synchronization block , It doesn't happen naturally lock and unlock operation , So the tube lock rule doesn't apply .
- continue , because value Variables are not volatile Keyword modification , therefore volatile The variable rule does not apply .
- continue , Later threads start 、 End 、 Interruption rules and object termination rules have nothing to do with this .
- Last , Because there is no applicable antecedent rule , So there's no way to talk about the last transitivity .
therefore , Even if we know threads A Ahead of thread in operation time B, But we still can't determine the thread B getValue() method . let me put it another way , The operation in this is not thread safe .
Then how to fix this problem ?
We have at least two simpler options :
- The first one is , Or put
getter/setterMethods are defined assynchronizedMethod , In this way, the pipe locking rules can be applied . - The second kind , Or put
valueDefined asvolatileVariable , becausesetterMethod pairvalueThe modification of does not depend onvalueOriginal value of , SatisfyvolatileKeyword usage scenarios , In this way, you can applyvolatileVariable rules to achieve antecedent relationships .
Through the above case , We know : An operation time occurs online , This does not mean that this operation will 「 Happen first 」. So if an operation 「 Happen first 」, Can we deduce that this operation must occur first in time ? Not really , Because it is possible to reorder instructions .
// The following operations are performed in the same thread
int j = 1;
int j = 2;
The above code is executed in the same thread , Execute the sequence rules according to the program ,int i = 1; The operation of occurs first in int j = 2;, but int j =2 The code may be executed by the processor first , Because they are not interdependent , It does not affect the correctness of the principle of first occurrence .
The above two cases together prove a conclusion : There is not much relationship between the sequence of time and the principle of first occurrence , So we should not be disturbed by the time sequence when we measure the concurrent security problems , Everything must be based on the principle of first occurrence .
summary
happens-before Principle shared 8 Article principle , It's right Java Simplification of memory model rules , Help programmers improve programming efficiency .
There is not much relationship between the sequence of time and the principle of first occurrence , When we measure concurrency security, we should not be disturbed by the time sequence , Everything must be based on the principle of first occurrence .



![leetcode:522. Longest special sequence II [greed + subsequence judgment]](/img/43/9b17e9cb5fee9d14c2986a2141889d.png)


![[hcie-rs review mind map] - STP](/img/b5/b89e59fe7f23bf23feeadb991acba7.png)


