happens-before rule

concept

There is a "happens-before" rule in the Java language, which is the partial order relationship between two operations defined in the Java memory model. If operation A occurs before operation B, it means that in Before operation B occurs, the impact of operation A can be observed by operation B. The "impact" includes modifying the value of shared variables in memory, sending messages, calling methods, etc., which is basically the same as the time sequence. big relationship. This principle is particularly important. It is the main basis for judging whether there is competition in data and whether threads are safe.

Example: Suppose there are three threads A
, B, and C, and they correspond to the following three operations:
A thread operation: i=1;
B thread operation: j=i;
C thread operation: i=2;
Operation "i=1" happens-before operation "j=i" in thread B, then it can be guaranteed that after the operation of thread B is executed, the value of variable j must be 1, that is, thread B observes the operation in thread A" i=1"; now, we still maintain the happens-before relationship between thread A and thread B, and thread C appears between the operations of thread A and thread B, but C and B do not happen -before relationship, then the value of j is uncertain. The influence of thread C on variable i may or may not be observed by thread B. At this time, thread B has the risk of reading data that is not the latest, and does not have thread safety.

Happens-before rules closely related to programmers

Program order rules: every operation in a thread happens-before any subsequent operations in that thread. That is to say, in a separate thread, in accordance with the execution flow sequence of the program code, the operation performed first (in time) happens-before (in time) after the operation.
Monitor lock rules: unlocking a monitor lock occurs-before the subsequent locking of the monitor lock.
Volatile variable rule: Writes to a volatile field occur-before any subsequent reads of the volatile field.
Transitive: If A happens-before B, and B happens-before C, then A happens-before C.

What is the difference between "sequence of execution" and "happens-before"?
1. If thread operation A happens before thread operation B in time, does it mean that operation A happens-before operation B? For
example:

private int value = 0;  

public int getValue(){  
    return value;  
}  
public void setValue(int value){  
    this.value = value;  
}  

Assuming that thread A and thread B exist, thread A calls the setValue(3) operation first (first in time), and then (later in time) thread B calls the getValue() method of the same object, then thread B gets the return Does the value have to be 3? This is obviously not guaranteed, because thread A and thread B do not satisfy the happens-before relationship, that is to say, the operation done by thread A may not be known by thread B. In fact, it is still a thread visibility problem, because each thread Each has its own independent working memory. The operation performed by thread A cannot immediately refresh the main memory, so thread B cannot obtain the latest value.
Solution: You can define both the setValue(int) method and the getValue() method as a synchronized method, or you can define the value as a volatile variable (the modification of the value does not depend on the original value of the value, which is in line with the volatile usage scenario), corresponding to Clauses 2 and 3 of the happens-before rule. Note that it is not possible to define only one of the setValue(int) method and the getvalue() method as a synchronized method. All reads and writes of the same variable must be synchronized to ensure that stale data is not read, only synchronous read or Writing is not enough.

2. Operation A happens-before operation B, does it mean that operation A happens-before operation B in time?
Example:

x = 1
y = 2;

Suppose the same thread performs the above two operations: operation A: x=1 and operation B: y=2. According to Article 1 of the happens-before rule, operation A happens-before operation B, but due to the reordering of the compiler's instructions (the Java language specification stipulates that the JVM thread maintains serialization semantics internally, that is, as long as the final result of the program is equal to Its result in a strictly sequential environment, then the execution order of the instructions may be inconsistent with the order of the code. This process is called reordering of instructions. The meaning of instruction reordering is that the JVM can adapt to the characteristics of the processor (CPU (multi-level cache system, multi-core processor, etc.) appropriately reorder machine instructions to make machine instructions more in line with the execution characteristics of the CPU and maximize the performance of the machine. In the absence of synchronization, the compiler, processor and running There may be some unexpected adjustments to the execution order of operations) and other reasons, operation A may be executed by the processor later than operation B in time, but this does not affect the correctness of the happens-before principle.

Summary: In the end, there must be some order between one operation and the other, either one operation either precedes or precedes the other, or occurs simultaneously with both operations. Simultaneity is entirely possible, especially with multiple CPUs. However, there may be no happens-before relationship between the two operations, that is to say, it may happen that operation A does not happen-before operation B, and operation B does not happen-before operation A. In the mathematical term happens- The before relation is a partial order relation. Two operations with a happen-before relationship cannot happen at the same time. An operation A happens-before operation B. They must be completely staggered in time, which is actually one of the semantics of synchronization (exclusive access).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325607298&siteId=291194637