atomicity, memory visibility, and reordering--re-understanding of synchronized and volatile

Source: Internet
Author: User

First, the atomic nature

Atomic manipulation means that the corresponding operation is a single, indivisible operation. For example, performing a count++d operation on the INT variable count is not an atomic operation. Because count++ can actually be decomposed into 3 operations: (1) reads the current value of the variable count, (2) takes the current value of count and 1 for the addition operation; (3) assigns the added value to the Count variable.

In a multithreaded environment, non-atomic operations can be interfered by other threads. For example, if the corresponding code is not synchronized (synchronization), the value of the count variable may have been modified by another thread when performing a 2nd operation. Of course, the Synchronized keyword can help us achieve atomic operations to avoid this kind of interference between threads.

The Synchronized keyword implements the atomic nature of the operation, in essence: the exclusivity of the critical section (Critical) included in the keyword allows only one thread to execute code in the critical section at any one time, This allows the code in the critical section to represent an atomic operation. This point is basically clear to all. However, another role played by the Synchronized keyword-to ensure memory Visibility-is also a place we should review.

Second, memory visibility

When the CPU executes the code, the value of the variable accessed in the code may be cached to the CPU buffer in order to reduce the time consumed by the variable access, so that the corresponding code can be read from the CPU cache instead of the main memory when the corresponding tag accesses the variable again. Similarly, the code's modifications to the values of these cached variables may be written only to the CPU buffers, not to the primary memory. Because each CPU has its own cache, the contents of one CPU cache are not visible to other CPUs. This causes other threads running on other CPUs to be unable to "see" The changes that the thread makes to a variable value. This is known as memory visibility.

Another function of the Synchronized keyword is to ensure that when a thread executes code in a critical section, the modified variable value is visible to the thread that later executes the critical section. This is important for ensuring the correctness of multithreaded code.

The volatile keyword can also guarantee memory visibility. That is, a thread changes the value of a variable that is decorated with the volatile keyword and is always visible to other threads that access the variable. That is, other threads do not read an "expired" variable value. Therefore, someone compares the volatile keyword with the internal lock represented by the Synchronized keyword, which is called a lightweight lock. This is not an appropriate address, the volatile keyword can only guarantee memory visibility, it does not like the Synchronized keyword represented by the internal lock can guarantee the atomic nature of the operation. The core mechanism of the volatile keyword for memory visibility is that when a thread modifies the value of a volatile modified variable, that value is written to main memory (that is, RAM), not just the buffer of the CPU on which the current thread resides. The value of the variable stored in the other CPU's buffers is therefore invalidated (thereby updating the "new value" of the variable in main memory). This guarantees that when other threads access the volatile modified variable, it is always possible to get the latest value for that variable.

Third, order reordering

Another effect of the volatile keyword is that it prohibits command reordering (re-order). The compiler and CPU may reorder instructions in order to improve the execution of the instructions, which may make the actual execution of the code not in the way we think. For example, the following instance variable initializes the statement:

Private SomeClass someobject = new SomeClass ();

The above statement is very simple: (1) Create an instance of the class SomeClass, and (2) Assign a reference to the instance of the class SomeClass to the variable someobject. However, due to the reordering of commands, the actual order of execution of this Code may be: (1) Allocate a section of memory space for storing SomeClass instances, (2) Assign a reference to the memory space to the variable Someobject, and (3) Create an instance of the class SomeClass. Therefore, when other threads access the value of the someobject variable, it is only a reference to a memory space that stores the SomeClass instance, and the initialization of the corresponding SomeClass instance of that memory space may not be complete, which can lead to some unintended results. The prohibition of ordering reordering allows the above code to be executed in the order that we want them to be, as the code expresses.

Preventing command reordering may cause the compiler and CPU to be unable to optimize some of the instructions, but it makes the code execution seem to be more consistent with our expectations in some way.

Iv. the difference between Volatile and synchronized

1.volatile essentially tells the JVM that the value of the current variable in the register (working memory) is indeterminate and needs to be read from main memory, while synchronized locks the current variable, and other threads are blocked only if the variable is accessible to the thread.
2.volatile can only be used at variable levels; Synchronized can be used at variable, method, and class level.
3.volatile can only implement variable change visibility, not guaranteed atomicity (thread a modifies the variable is not finished, another thread B can see the modified value, and can modify the variable, without waiting for a release lock, because the volatile variable is not locked) , while synchronized can guarantee the change of the visibility and atomicity of variables.
4.volatile does not cause a thread to block; Synchronized can cause thread blocking and context switching.
5.volatile tagged variables are not optimized by the compiler; Synchronized tagged variables can be optimized by the compiler.

Article picked from: 53152737

Atomicity, memory visibility, and reordering--re-recognize synchronized and volatile

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.