Reorder
When the program is executed , To improve performance , Compilers and processors often reorder instructions . Reordering is divided into three types .
- Compiler optimized reordering . Compiler without changing the semantics of single thread program , You can rearrange the execution order of statements .
- Instruction level parallel reordering . Modern processors use instruction level parallelism to execute multiple instructions in an overlapping way . If there is no data dependency , The processor can change the execution order of machine instructions corresponding to statements .
- Reordering of memory system . Because the processor uses cache and read / Write buffer , The loading and storage operations may be performed out of order .
Reordering can cause memory visibility problems in multithreaded programs . Instruction parallel reordering and memory system reordering belong to processor reordering , Reorder for processor ,JMM Will ask for Java When the compiler generates instructions , Insert specific Memory barrier instructions , Disable specific types of processor reordering through memory barrier instructions .
Memory barrier type
| Barrier type | Instruction example | explain |
|---|---|---|
| LoadLoad Barriers | Load1; LoadLoad; Load2 | Make sure Load1 Data loading precedes Load2 And all subsequent loading instructions loading |
| Store Store Barriers | Store1; StoreStore;Store2; | Make sure Store1 Data is visible to other processors before Store2 And all subsequent storage instructions |
| LoadStore Barriers | Store1; StoreLoad; Load2 | Make sure Store1 Data loading precedes Store2 And all subsequent storage instructions are flushed into memory |
| StoreLoad Barriers | Store1; StoreLoad; Load2 | Make sure Store1 Data becomes visible to other processors ( Refresh to memory ) Precede Load2 And all subsequent loading instructions loading . |
happen-before
from JDK5 Start ,Java Use JSR-133 Memory model ,JSR-133 Use happen-before The concept of memory visibility between operations . stay JMM in , If the result of one operation needs to be visible to another , Then there must be a happen-before Relationship .
Happen-before The following rules :
- Rules of procedure sequence : Every operation in a thread ,happen-before Any subsequent operation in the thread .
- Monitor lock rules : Unlocking a lock ,happen-before Then lock the lock .
- volatile Variable rule : To a volatile Domain writing ,happen-before In any follow-up to this volatile Domain reading
- Transitivity : If A happen-before B, And B happen-before C, that A happen-before C.
Three factors that cause concurrency security
visibility
visibility : Modification of shared variables by a thread , Another thread can see immediately .
// Threads 1
int a = 0;
a = 1;
// Threads 2
int b = a;
If a thread 1 from cpu1 perform , Threads 2 from cpu2 perform , When executed a=1 when , Will be able to a The initial value of the 0 Load into cpu1 In the cache of , Then it's assigned to 1, here cpu1 In cache a The value of becomes 1, But it has not been flushed to main memory immediately . here cpu2 perform b=a Will read from main memory a The value of is then loaded into cpu2 The cache of , here a The value in main memory is still 0, that b The value of is now 0 instead of 1. That's the visibility issue , Threads 1 The variable i After modification , Threads 2 No thread immediately seen 1 Modified value . Threads 1 For shared variables a After modification , Threads 2 Did not immediately see the changes after a Value , This raises the issue of visibility .
Atomicity
Atomicity : One or more operations Either all of them are executed and the execution process will not be interrupted by any factors , Or they don't do it .
Orderliness
Reordering can cause memory visibility problems in multithreaded programs







![[leetcode] balanced binary tree](/img/77/a37557295646010326dac024cf869a.jpg)

