We often encounter three problems in concurrent programming: atomicity, Visibility, and order, and here are a few three questions to analyze. If there are any mistakes, please criticize and correct them. first, the atomic nature
Atomic lines: One or more operations as a whole, either all executed or not executed, and the operation is not interrupted by the thread scheduling mechanism during execution, and once the operation has started, it runs to the end with no context switch in between.
We use bank account transfer problem to explain the image of atomicity (of course, bank account transfer involves more problems, we are here to compare)
Example one:
For example, John to Lee four transfer 200 yuan, can be broken down into the following steps:
1 minus 200 Yuan from John Account
2) Add 200 yuan to Dick account
If only step 1 is performed and no Step 2 is performed, the problem comes, John said he gave Lee four money, Dick said he did not receive, the bank how to deal with this matter. Adding atomicity to this operation can be a good solution to the transfer problem.
Example two:
In Java development, we often use the following statements
int i = 0; Statement 1
i++; Statement 2
Statement 1 is an atomic operation.
The decomposition steps for statement 2 are:
1) Get the value of I;
2) to calculate the value of i + 1;
3 The value of I + 1 is assigned to I;
When you perform the 3 steps above, you can switch threads, so statement 2 is not an atomic operation two, visibility
Visibility means that when multiple threads access the same variable, a thread modifies the value of the variable, and other threads can immediately see the modified value.
Example:
private int i = 0;
private int j = 0;
Thread 1
i = ten;
Thread 2
j = i;
Thread 1 modifies the execution step of the value of I to 10 o'clock:
1 assigns 10 to the I variable in the thread 1 working memory;
2 assigns the value of the I variable in thread 1 working memory to the I variable in main memory;
When thread 2 executes j = i, thread 2 executes the steps:
1 reads the value of the I variable in the main memory into the working memory of thread 2;
2 reads the value of the J variable in main memory into the working memory of thread 2;
3 Assign the value of the I variable in thread 2 working memory to the J variable in the working memory of thread 2;
4 Assign the value of J variable in thread 2 working memory to the J variable in main memory;
If thread 1 finishes step 1, Thread 2 starts execution, and the value of the I variable in main memory is still 0, then thread 2 Gets the value of the I variable of 0 instead of 10.
This is the visibility issue, and thread 2 does not immediately see the value modified by thread 1 after the change to the I variable has been made to thread 1. third, the order of
Ordering: The order in which the program executes is executed in the order of the Code.
Example one:
int i = 0;
int j = 0;
i = ten; Statement 1
j = 1; Statement 2
Statements may be executed in the following order:
1) Statement 1 Statement 2
2) Statement 2 statement 1
Statement 11 is scheduled to execute before statement 2. The answer is no, there may be an execution rearrangement (instruction Reorder). In general, the processor in order to improve the efficiency of the program, the input code may be optimized, it does not guarantee that the execution sequence of each statement in the program in accordance with the order in the code, but it will ensure that the program in a single threaded environment, the results of the execution of the code sequence and the results
For example, in the above code, statement 1 and statement 2 who first executed the final program results did not affect, then it is possible in the execution, statement 2 first executed and statement 1 after execution.
Example two:
int i = 0; Statement 1
Int j = 0; Statement 2
i = i +; Statement 3
j = i * I; Statement 4
Statements may be executed in the following order:
1 Statement 1 Statement 2 Statement 3 Statement 4
2 Statement 2 Statement 1 Statement 3 Statement 4
3 Statement 1 Statement 3 Statement 2 Statement 4
Statement 3 is not possible after statement 4 because the compiler takes into account the dependency problem of the data when it makes the instruction rearrangement, and statement 4 relies on statement 3, so statement 31 is scheduled to execute before statement 4.
Next we talk about multithreaded environments.
Example three:
Private Boolean flag = false;
private context = null;
Thread 1 Context
= Loadcontext (); Statement 1
flag = true; Statement 2
//thread 2 while
(!flag) {
thread.sleep (1000L);
}
DoWork (context);
Statements may be executed in the following order:
1) Statement 1 Statement 2
2) Statement 2 statement 1
Because statement 1, Statement 2, in thread 1 is not dependent, a command rearrangement may occur. If a command rearrangement occurs, thread 1 executes statement 2 first, when thread 2 begins execution, at which point the flag value is true, so thread 2 continues to execute the DOWRK (context), and the context is not initialized, causing a program error.
Therefore, it can be concluded that the command rearrangement will not affect the results of single-threaded execution, but it will affect the correctness of the results of multithreaded concurrent execution.
Summary: A properly executed concurrent program must be atomic, visible, and orderly. Otherwise, it may cause the program to run incorrectly and even cause a dead loop.