Friday, January 31, 2020

What is happens-before in Java Concurrency? An example

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep

A couple of days ago, one of my readers messaged me on LinkedIn about a Java interview question he has recently faced - what is the happens-before relationship in Java concurrency? What is the benefit of it, and how exactly it works? He kind of has some ideas about that its related to the Java Memory Model and provides some sort of visibility guaranteed but couldn't explain with conviction to his interviewer, particularly with a code example and was a bit disappointed. He then asked me if I can write an article about it. I said you should have read the Java concurrency in Practice book before the interview, that would have helped, but nonetheless, I liked the idea to just provide a quick overview of what is the happens-before relationship between threads in Java.

To understand the happens-before relationship, you need to first understand what problems can occur if the same variable is accessed by multiple threads? particularly if one thread writes into the variable, and one thread read from it at the same time.

For example, let's say we have the following code, which is executed by Thread T1, (note, integer variable y is initialized before x)

int y = 1;
int x = 2;

Now, we have another piece of code which is executed by another thread T2 where the value of both the variable is printed (note variable x is printed before y) :

System.out.print(x);
System.out.println(y);

What do you think? What should be printed on the screen? If this code is executed by the same thread, then it's guaranteed that 2 and 1 will be printed, but with multiple threads, there is no guaranteed behavior. It's entirely possible that T2 could not see the assignments made by T1 and just print 0 for both x and y.

It's also possible that it can just see the initialization of either x or y and print accordingly.

This is scary and unpredictable, think what will happen if X is money in your bank account, you definitely want a predictable behavior.

That's where happens-before comes into play. It provides some sort of ordering and visibility guarantee. There is a lot of rule concerning Happens-before (which you can read on Java Concurrency in Practice). Still,  the most important one is if there is a synchronization like a synchronized block or a volatile variable then.

- "A volatile write will happen before another volatile read."
- "An unlock on the synchronized block will happen before another lock."

And, (this is most important)

All the changes which are visible to T1 before a volatile write or a synchronized unlock will be visible to thread T2 after a volatile read of the same variable or locking on the same monitor.

This statement is the most important one, and it can be best understood by the following diagram:

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep
Image credit - Java Concurrency in Practice

You can see that before unlock, thread T1 can see y=1 and x=1, so after T2 gets a lock on the same object, it can also see y=1 and x=1, even though y is not a volatile variable or read inside the lock or synchronized context. This is also true for volatile write and volatile read, which offers slightly less form of synchronization but a great alternative when it comes to visibility.

Now, let's go back to our example if we modify our code like this:

T1:
int y = 1;
volatile int x = 2;

T2:
System.out.print(x);
System.out.println(y)

What do you think? What does the code print now? 2 and 1 or 2 and 0?

Well, if you apply the happens-before than when T1 does a volatile write, and T2 does a volatile read, then it will also see the value of y=1, which is not volatile. Isn't behavior is now more predictable.

The critical thing to remember here is that even the value of a non-volatile variable is visible to thread T2. This is just one example of a happens-before relationship but very useful in analyzing the behavior of a multi-threaded program.

If you are serious about improving your understanding of Java concurrency knowledge and skills, I strongly suggest you should read the Java Concurrency in Practice book by Brian Goetz, Joshua Bloch, Doug Lea and team, one of the best resources for Java developers.

Java Concurrency, Oracle Java Tutorial and Material, Oracle Java Study Materials, Oracle Java Prep

Related Posts

0 comments:

Post a Comment