Java memory Model-the principle of antecedent occurrence

Source: Internet
Author: User
Tags volatile

The Java language has a principle of "first occurrence" (Happens-before). This principle is very important, it is to judge whether the data is competitive, the thread is the security of the main basis, relying on this principle, we can be a few rules package to solve the concurrency of the two operations between the possible conflicts between all problems.
Now let's look at what the "antecedent" principle refers to. The first occurrence is a partial-order relationship between two operations defined in the Java memory model, and if operation a precedes operation B, it is said that the effect of operation A can be observed by Operation B before Operation B, "Impact" includes modifying the values of shared variables in memory, sending messages, calling methods, and so on. This sentence is not difficult to understand, but what does it mean? We can give an example to illustrate the following three lines of pseudo-code, as follows:

        // The following actions are performed        in thread A I=1;         // The following actions are performed        in thread B j=i;         // The following actions are performed        in thread C i=2;

Assuming that the operation "I=1" in thread a precedes the operation "j=i" of thread B, then we can determine that the value of the variable J must be equal to 1 after the operation of course B, and the basis of this conclusion is two, one is that the result of "i=1" can be observed according to the principle of antecedent occurrence; second, before thread C comes in , no other thread modifies the value of the variable I after the end of the thread a operation. Now consider thread C, we still maintain the antecedent relationship between threads A and B, and C appears between the actions of thread A and B, but C and B do not have a prior relationship, and what is the value of J? The answer is not sure! Both 1 and 2 are possible, because the impact of thread C on the variable I may be observed by thread B, or not, when thread B has the risk of reading to outdated data without multithreading security.

Eight "natural" first-sex

The following are some of the "natural" antecedent relationships in the Java memory model, which are already present without any Synchronizer assistance and can be used directly in the encoding. If the relationship between the two operations is not there and cannot be deduced from the following rules, they are not guaranteed to be sequential, and the virtual machine can reorder them arbitrarily.

  • Program Order rule (Programorderrule): In a thread, according to the sequence of program code, the preceding operation occurs in the previous operation. It should be accurate to control the flow order rather than the program code order, because the structure of branching, looping, etc. is considered. The happens-before relationship essentially and as-if-serial semantics is one thing:
    • As-if-serial semantics guarantees that the execution results of a single-threaded program are not changed, and that the happens-before relationship guarantees that the execution results of correctly synchronized multithreaded programs are not changed.
    • As-if-serial semantics creates a mirage for programmers who write single-threaded programs: single-threaded procedures are executed in the order of the program. The Happens-before relationship creates a mirage for programmers who write correctly synchronized multithreaded programs that are executed in the order specified by Happens-before. The purpose of as-if-serial semantics and Happens-before is to improve the degree of parallelism of program execution without changing the results of program execution.

  • Tube Lock Rule (monitorlockrule): A unlock operation occurs after the lock operation that faces the same lock. The same lock must be emphasized here, and the "back" refers to the chronological order of the time.
  • Volatile variable rule (volatilevariablerule): The write operation of a volatile variable precedes the read operation of the variable, and the "back" here also refers to the order of time.
  • Thread Initiation Rule (threadstartrule): The Start () method of the thread object precedes every action on this thread.
  • Thread termination rule (Threadterminationrule): All operations in a thread first occur on termination detection of this thread, we can end with the Thread.Join () method, Thread.isalive () The return value of the device detects that the thread has terminated execution.
  • Thread Break Rule (threadinterruptionrule): The invocation of 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 (Finalizerrule): The initialization of an object (the end of the execution of a constructor) occurs first at the beginning of its finalize () method.
  • Transitivity (transitivity): If operation a first occurs in operation B, Operation B first occurs in Operation C, it can be concluded that operation a precedes operation C.
As an example,

The Java language does not need any synchronous means to ensure that the first occurrence of the rule can be set up above, the following shows how to use these rules to determine whether the operation is sequential, for read and write shared variables, is the thread is safe, we can also from the following example to feel the " What is the difference between the sequencing of time and the first occurrence?

 private  int  value = 0;  public  int   GetValue () {  value;  public  void  SetValue (int   this . Value = value; }

The above code shows a common set of getter/setter methods, assuming that there are threads A and B, thread a first (in time) called "SetValue (1)", then thread B calls the same object "GetValue ()", So what is the return value that thread B receives?
We analyze the rules of the first occurrence principle in turn, because two methods are called by thread A and B, not in a thread, so the program order rule is not applicable here; Lock and unlock operations do not occur naturally because there is no synchronization block, so the pipe lock rule does not apply Because the value variable is not decorated with the volatile keyword, the volatile variable rule does not apply, and the subsequent thread initiation, termination, break rule, and object termination rules are completely out of the question. Because there is no applicable antecedent rule, so the last pass cannot be discussed, so we can determine that although thread A is in operation time before thread B, it cannot be determined the return result of the "GetValue ()" method in B, in other words, the operation is not thread-safe.
So how do you fix this problem? We have at least two simpler options: either define the Getter/setter method as the synchronized method, so that you can apply the enhancement lock rule, or define value as a volatile variable, Because the setter method's modification of value does not depend on the original value of value, the volatile keyword usage scenario is satisfied, so that the volatile variable rule can be applied to achieve the antecedent relationship.
From the above example, we can conclude that an operation "occurs first" does not mean that the operation will be "antecedent", that if an operation "first occurrence" whether it can be deduced that this operation must be "time to occur"? Unfortunately, this inference is also not tenable, a typical example is the "order reordering" as mentioned many times.

// The following operations execute Inti=1 in the same thread ; INTJ= 2;

The two assignment statements of the above code are in the same thread, according to the Rules of program order, the operation of "Inti=1" occurs in "intj=2", but the code of "intj=2" may be executed by the processor first, which does not affect the correctness of the principle of antecedent occurrence. Because we have no way of perceiving this in this thread.

Summarize

The above two examples combine to prove a conclusion: the sequence of time and the principle of the first occurrence of the basic is not much of a relationship, so we measure the concurrency of security issues not to be affected by the time sequence of interference, all must be based on the principle of first occurrence.

Resources

Zhou Zhiming: "In-depth understanding of Java virtual machines"

Fang Fei: "The Art of Java concurrent programming"

Java memory Model-the principle of antecedent occurrence

Related Article

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.