Detailed explanation of volatile and synchronized

1. Background

Speaking of concurrent programming, we have to talk about the two keywords volatile and synchronized . These two keywords are often asked in interviews. Let’s introduce these two keywords and their similarities and differences.

First of all, we first understand two terms about thread safety: memory visibility and execution order

Memory visibility: As the name implies, it is the visibility of thread execution results to other threads in memory

Execution sequence: control the execution sequence of the code and whether it can be executed concurrently

Two, volatile

Volatile solves the problem of memory visibility

2.1 volatile principle

The volatile principle is implemented based on the CPU memory barrier instruction

2.2 Visibility of volatile modified variables

Volatile is a variable modifier, and the modified variable has memory visibility

In general, when a thread is executing, in order to speed up the efficiency of the program, the main memory data is first copied to the thread local (register or CPU cache), and the result is refreshed from the thread local cache to the main memory after the operation is completed. , This will lead to a process that needs to be synchronized to the main memory after the modification is put into the variable, and at this time, the other thread sees the variable value before the modification, which will cause inconsistency

In order to solve the problem of memory visibility in the above-mentioned multithreading, the volatile keyword is introduced, so why can it solve the memory visibility problem?

Answer: volatile will make all reads and writes of volatile variables directly read and write the main memory instead of reading and writing the thread local cache first, thus ensuring the memory visibility of the variable

2.3 volatile prohibits instruction rearrangement 

Volatile can prohibit instruction rearrangement

Instruction rearrangement: In order to improve the efficiency of the program, the processor may optimize the input code. It does not guarantee that the execution order of each statement is consistent with the order in the code, but it will ensure that the final execution result of the program and the result of the code sequence execution are Consistent. Instruction reordering will not affect the execution of a single thread, but it will affect the correctness of concurrent execution of threads

When the thread executes the read and write operation of the volatile modified variable, other threads must have completed the operation of this variable, and the result has been synchronized to the main memory, that is, visible to other threads, this thread has no problem with the variable operation again of

2.4 Scope of use of volatile

The volatile keyword can only achieve the atomicity of operations on primitive variables (such as boolen, short, int, long, etc.), and cannot guarantee the atomicity of compound operations , such as i++

i++ is actually composed of three atomic operations: read i; inc; write i. If multiple threads execute i++ at the same time, volatile can only guarantee that the i they operate on is the same piece of memory, but it cannot guarantee the correctness of the result of i. The reasons are as follows:

For example, there are two threads A and B performing i++ operations on volatile modified i. The initial value of i is 0. When thread A executes i++, it just reads the value of i 0, and then it switches to thread B. Thread B (from memory Middle) Read the value of i is also 0, then switch to the A thread to continue the i++ operation, after the completion of the i is 1, then switch to the B thread, because it has been read before, so continue to perform the i++ operation, The final result i is 1, and the value of i in the A and B threads synchronized to the main memory are both 1.

2.5 volatile usage scenarios

1. The write operation to the variable does not depend on the current value of the variable, or only a single thread updates the value of the variable

2. The variable is not included in the invariant with other variables

三、synchronized

Synchronized not only solves the problem of memory visibility, but also solves the problem of execution order

synchronized can modify code blocks or methods, both to ensure visibility and atomicity

The specific implementation process of synchronized lock: https://blog.csdn.net/ywlmsm1224811/article/details/108322059

3.1 synchronized principle

synchronized is implemented based on monitor

3.2 synchronized modified code block or method to ensure memory visibility

Through synchronized or Lock, it can be ensured that only one thread acquires the lock and executes the synchronization code at the same time, and the modification of the variable is flushed to the main memory before the lock is released

3.3 Synchronized modified code block or method guarantees atomicity

The thread either does not execute (the thread does not acquire the object lock), or the thread executes to the end (the thread acquires the object lock), until the execution is completed and the lock is released

3.4 The scope of synchronized use

synchronized can modify not only code blocks, but also methods

3.5 synchronized usage scenarios

Need to control the method of multi-threaded access or update variables

Fourth, the similarities and differences between volatile and synchronized

4.1 Similarities

Both volatile and synchronized ensure memory visibility

4.2 Differences

1. Volatile can only be used at the variable level, synchronized can be used at the variable, method, and class level

2. Volatile can only achieve the visibility of the modification of variables, and cannot guarantee the atomicity, while synchronized can guarantee the visibility and atomicity of the modification of variables

3. Volatile will not cause thread blocking, while synchronized may cause thread blocking

4. Variables marked with volatile will not be optimized by the compiler, while variables marked with synchronized can be optimized by the compiler

5. Due to the difference in 4, the performance of volatile is better than synchronized in some cases

Five, summary

From the above understanding of volatile and synchronized, we know that volatile cannot replace synchronized. The main reason is that volatile cannot guarantee the atomicity of operations.

reference:

https://blog.csdn.net/SEU_Calvin/article/details/52370068

https://blog.csdn.net/suifeng3051/article/details/52611233

https://blog.csdn.net/suifeng3051/article/details/52611310

Guess you like

Origin blog.csdn.net/ywlmsm1224811/article/details/103166419
Recommended