While reading Java docs on Memory Consistency errors. I find points related to two actions that creates happen - before relationship:
When a statement invokes 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.
When a thread terminates and causes a 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.
I am not able to understand their meaning. It would be great if someone explain it with a simple example.
If one action 'x' is visible to and ordered before another action 'y', then there is a happens-before relationship between the two actions indicated by hb(x, y). If x and y are actions of the same thread and x comes before y in program order, then hb(x, y).
When the concept of multithreading is implemented, it is possible that changes made by one thread wouldn't be visible to the other thread. This indicates that the view of each thread is inconsistent with respect to each other. This is known as memory consistency error.
Memory consistency errors occur when different threads have inconsistent views of what should be the same data. The causes of memory consistency errors are complex and beyond the scope of this tutorial. Fortunately, the programmer does not need a detailed understanding of these causes.
Java memory model is divided between Thread Stacks (One for each thread) and a heap area. Thread Stack: It is a thread specific memory area and contains local variables, methods call information etc. JVM stacks could be of fixed size or variable size.
Modern CPUs don't always write data to memory in the order it was updated, for example if you run the pseudo code (assuming variables are always stored to memory here for simplicity);
a = 1 b = a + 1
...the CPU may very well write b
to memory before it writes a
to memory. This isn't really a problem as long as you run things in a single thread, since the thread running the code above will never see the old value of either variable once the assignments have been made.
Multi threading is another matter, you'd think the following code would let another thread pick up the value of your heavy computation;
a = heavy_computation() b = DONE
...the other thread doing...
repeat while b != DONE nothing result = a
The problem though is that the done flag may be set in memory before the result is stored to memory, so the other thread may pick up the value of memory address a before the computation result is written to memory.
The same problem would - if Thread.start
and Thread.join
didn't have a "happens before" guarantee - give you problems with code like;
a = 1 Thread.start newthread ... newthread: do_computation(a)
...since a
may not have a value stored to memory when the thread starts.
Since you almost always want the new thread to be able to use data you initialized before starting it, Thread.start
has a "happens before" guarantee, that is, data that has been updated before calling Thread.start
is guaranteed to be available to the new thread. The same thing goes for Thread.join
where data written by the new thread is guaranteed to be visible to the thread that joins it after termination.
It just makes threading much easier.
Consider this:
static int x = 0; public static void main(String[] args) { x = 1; Thread t = new Thread() { public void run() { int y = x; }; }; t.start(); }
The main thread has changed field x
. Java memory model does not guarantee that this change will be visible to other threads if they are not synchronized with the main thread. But thread t
will see this change because the main thread called t.start()
and JLS guarantees that calling t.start()
makes the change to x
visible in t.run()
so y
is guaranteed to be assigned 1
.
The same concerns Thread.join();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With