JVM Learning record-java memory model (ii)

Source: Internet
Author: User
Tags volatile

Special rules for volatile types of variables

Keyword volatile can be said to be the most lightweight synchronization mechanism provided by a Java virtual machine.

When dealing with the problem of multi-threaded data competition, it is not only possible to use the Synchronized keyword, but also can be achieved using volatile.

The Java memory model specifically defines special access rules for Volatitle, which has the following two features when a variable is defined as volatile:

The first is to ensure that this variable is visible to all threads, where "visibility" means that when a thread modifies the value of the variable, the new value is immediately known to other threads. The normal variable cannot do this, the value of the normal variable, the transfer between threads is required through the main memory of the Stroe and write operations and read and load operations to achieve. volatile only guarantees the visibility of variables, but does not guarantee the atomicity of variable operations.

The second is to prohibit command reordering optimizations, and ordinary variables will only guarantee that the correct results will be obtained in the execution of the method in all places that depend on the result of the assignment, and that the sequence of variable assignment operations is consistent with the order of execution in the program code.

Since volatile variables can only guarantee visibility, we still have to use shackles (using atomic classes in synchronized or java.util.concurrent) to guarantee atomicity in an operation scenario that does not conform to the following two rules.

    • The result of the operation does not depend on the current value of the variable, or can ensure that only a single thread modifies the value of the variable.
    • Variables do not need to participate in invariant constraints with other state variables.

The following code is good for using volatile variables to control concurrency:

    volatile Boolean shutdownrequested;          Public void shutdown () {        true;    }          Public void doWork () {        while ( !  shutdownrequested) {            //dosomething;         }    }
Atomicity, Visibility and ordering

The Java memory model is built around the 3 characteristics of how atomicity, visibility, and ordering are handled in the concurrency process, and the following are some of the 3 features:

atomicity (atomicity)

Atomic variable operations that are directly guaranteed by the Java memory model include read, load, assign, use, store, and write, and I can basically assume that the access read and write of the basic data type is atomic. If a wider range of atomicity assurances is required, the Java memory model also provides lock and unlock operations to meet this requirement, although the virtual machine does not develop these two operations directly to the user, but provides a higher level of bytecode instruction to implicitly use the two operations. The two bytecode instructions in Java code are the synchronization block----synchronized keyword, so the operation between synchronized blocks is also atomic.

Visibility (Visibility):

visibility means that when a thread modifies the value of a shared variable, other threads can immediately know the change. the Java memory model realizes visibility by synchronizing the new value back to main memory after the variable is modified, and by refreshing the variable value from the main memory before the variable is read, which relies on the main memory as the medium of delivery, whether it is a normal variable, a volatile variable, or a normal variable. The difference between a normal variable and a volatile variable is that the special rules for volatile ensure that the new value is immediately synchronized to the main memory and flushed from the main memory immediately before each use.

In addition to volatile, synchronized and final can also achieve visibility, and the visibility of synchronized is determined by the "unlock operation on a variable, you must first synchronize this variable back to the main memory" this rule obtains, Final is because the final modified field is completed once in the constructor, and the constructor does not pass the reference to "this", and the final field value is visible in other threads.

Order (Ordering):

The natural ordering of Java programs can be summed up in one sentence: If you look inside this thread, the operations are orderly, and if you look at another thread in one thread, all operations are unordered. The first half of the sentence refers to "line range is expressed as serial semantics", the second half sentence refers to the "order reordering" phenomenon and "working memory and main memory synchronization delay" phenomenon.

Java provides volatile and synchronized two keywords to ensure an orderly operation between threads, and volatile contains the semantics of fine-order reordering, while synchronized is made up of " A variable that allows only one thread to lock on it at the same time "this rule determines that two synchronized blocks holding the same lock can only be entered serially.

Principle of antecedent occurrence (Appens-before)

If all the ordering in the Java memory model is done only with volatile and synchronized, then there are some operations that can become cumbersome, but we do not perceive this in the Java code because there is an " antecedent " principle in the Java language.

Pre-occurrence is a partial-order relationship between two operations defined in the Java memory model, and if operation a precedes operation B, the effect of operation A can be observed by Operation B, which refers to modifying the values of shared variables in memory, sending messages, calling methods, and so on.

Here's an example:

    // The following operations execute    i = 7 in thread a;         // The following actions are performed    in thread B j = i;         // The following actions are performed    in thread C i = 9;

If thread a precedes thread B then the variable J must be 7 because thread A's operation is observed by thread B and is then affected, while thread C has not yet occurred, so J must be 7. However, if thread C appears between threads A and thread B, and thread C does not occur with thread B, then the effect of thread C on the variable I may be observed by thread B, or not, when thread B reads data that has an expiration risk and does not have multithreading security.

There are some "natural" antecedent relationships in the Java memory model that do not exist without any synchronizer assistance. If the relationship between the two operations is not in the following rules and cannot be deduced from the following rules, they are not guaranteed to be sequential, and the virtual machines can reorder them arbitrarily.

As follows:

Program Order rules: in a thread in the order of the program code, written in front of the operation first occurs in the operation after writing. It should be accurate to control the flow order rather than the program code order, because the structure of branching, looping, etc. is considered.

pipe Lock rule: A unlock operation occurs after the lock operation that faces the same lock. This refers to the same lock, while the "back" refers to the chronological order of the time.

volatile variable rules: for a variable's write operation first occurs after the face of this variable read operation, here "back" also refers to the time order.

thread start rule: The start () method of the thread object takes precedence over every action of this thread.

thread Termination rule: all operations in a thread first occur on termination detection of this thread, and we can detect that the thread has terminated execution by means of the end of the Thread.Join () method, the return value of thread.isalive (), and so on.

thread Break rule: the call to the thread interrupt () method occurs when the code of the interrupted thread detects that the interrupt event occurred, and can be detected by the thread.interrupted () method.

object Finalization rule: the initialization of an object (the completion of a constructor execution) precedes the beginning of its finalize () method.

transitivity: If operation a precedes operation B and Operation B precedes Operation C, it can be concluded that operation a takes precedence over Operation C.

How can I tell if the operation is sequential? The code examples are as follows:

    Private int value = 9;      Public Static int GetValue () {        return  value;    }          Public void setValue (int  value) {        this. Value = value;    } 

A common set of getter/setter methods, if thread A calls "SetValue (10)" First, then thread B calls the "GetValue ()" of the same object, what is the return value that thread B gets?

Analysis: Due to thread A and thread B two threads so the program order Rule does not apply, because there is no synchronization block, also does not occur lock and unlock, so the pipe lock rule does not apply, there is no volatile keyword, so Volatile variable rules also do not apply, followed by thread-initiation rules , thread-termination rules , thread-break rules , Object-terminating rules , and here is okay. Because there is no applicable antecedent rule, transitivity does not exist, so although thread A is in time with thread B, it cannot determine the return value of "GetValue ()" in thread B, which means that this operation does not have multithreading security.

So how to fix this problem, let this operation programming thread safe? There are two ways of doing this:

The Getter/setter method is defined as the Synchronized method.

Define value as a volatile variable.

Although the timing of the first implementation does not mean that it will happen first, if the first occurrence is not necessarily the first time on the implementation of it?

To illustrate:

    // The following operations are performed    in the same thread int i = ten;         int j = 20;

Because two assignment statements are executed in the same thread, according to the Rules of Program order, the first statement takes precedence over the second statement, but the code of the second statement may be executed by the processor first, which does not affect the correctness of the antecedent principle, since there is no way to perceive this in this thread.

Through two examples, summed up, the time sequence and the principle of the first occurrence of the basic relationship between the two, so the concurrency problem should not be affected by the time sequence of interference, to take the first occurrence of the principle prevail.

Java memory Model This part of the end, although it is recorded, but some places are still some foggy, it seems that later to review their knowledge, and according to this part of the knowledge to find one or two of the face of the question or is, their doubts and then through the search data to solve their doubts, so that can deepen the impression, After all, these theoretical knowledge, if not understood thoroughly, is easy to forget.

Will be naked resignation out looking for job interview, hope through their efforts in this period of time, in the interview process will not be hit very miserable.

JVM Learning record-java memory model (ii)

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.