Deep parsing of Java Memory Model: final — to
Original address: http://www.codeceo.com/article/java-memory-6.html
Compared with the locks and described earlier, reading and writing to the final field is more like ordinary variable access. For the final domain, the compiler and processor follow two reordering rules:
Next, we will illustrate the two rules through some example codes:
<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">void <span class="hljs-title">FinalExample (<span class="hljs-params">) { <span class="hljs-comment">//构造函数
i = <span class="hljs-number">1; <span class="hljs-comment">//写普通域
j = <span class="hljs-number">2; <span class="hljs-comment">//写final域
}
<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">void <span class="hljs-title">writer (<span class="hljs-params">) { <span class="hljs-comment">//写线程A执行
obj = <span class="hljs-keyword">new FinalExample ();
}
<span class="hljs-function"><span class="hljs-keyword">public <span class="hljs-keyword">static <span class="hljs-keyword">void <span class="hljs-title">reader (<span class="hljs-params">) { <span class="hljs-comment">//读线程B执行
FinalExample <span class="hljs-keyword">object = obj; <span class="hljs-comment">//读对象引用
<span class="hljs-keyword">int a = <span class="hljs-keyword">object.i; <span class="hljs-comment">//读普通域
<span class="hljs-keyword">int b = <span class="hljs-keyword">object.j; <span class="hljs-comment">//读final域
}
}
Here, suppose that one thread a executes the writer () method, and then another thread B executes the reader () method. Let's illustrate these two rules through the interaction of these two threads.
Write reordering rules for final fields
The reordering rule for writing final fields prohibits reordering the writes of final fields outside the constructor. The implementation of this rule includes the following two aspects:
Now let's analyze the writer () method. The writer () method contains only one line of code: finalexample = new finalexample(). This line of code consists of two steps:
Assuming that there is no reordering between the read object reference of thread B and the member domain of the read object (we will explain why this assumption is needed soon), the following figure is a possible execution timing: