The key to avoiding memory consistency errors is understanding the
happens-before relationship. This relationship is simply a
guarantee that memory writes by one specific statement are visible to
another specific statement. To see this, consider the following
example. Suppose a simple int
field is defined and
initialized:
int counter = 0;
counter
field is shared between two threads, A and B.
Suppose thread A increments counter
:
counter++;
counter
:
System.out.println(counter);
counter
will be visible to thread B — unless the
programmer has established a happens-before relationship between these
two statements.
There are several actions that create happens-before relationships. One of them is synchronization, as we will see in the following sections.
We've already seen two actions that create happens-before relationships.
Thread.start
, every
statement that has a happens-before relationship with that
statement also has a happens-before relationship with every
statement executed by the new thread. The effects of the code that
led up to the creation of the new thread are visible to the new
thread.
Thread.join
in another thread to return, then all the
statements executed by the terminated thread have a happens-before
relationship with all the statements following the successful join.
The effects of the code in the thread are now visible to the
thread that performed the join.
java.util.concurrent
package..