Reputation: 1850
Do I only need to mark a field volatile if multiple threads are reading it at the same time?
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
In my scenario, is there a happens-before relationship enforced (without the volatile keyword)?
Upvotes: 4
Views: 761
Reputation: 8928
You need the volatile keyword or some other synchronization mechanism to enforce the "happens before" relationship that guarantees visibility of the variable in threads other than the thread in which it was written. Without such synchronization, everything is treated as happening "at the same time", even if it doesn't by wall clock time.
In your particular example, one thing that may happen without synchronization is that the value written by thread A is never flushed from cache to main memory, and thread B executes on another processor and never sees the value written by thread A.
When you are dealing with threads, wall clock time means nothing. You must synchronize properly if you want data to pass between threads properly. There's no shortcut to proper synchronization that won't cause you headaches later on.
In the case of your original question, some ways proper synchronization can be achieved are by using the volatile
keyword, by using synchronized
blocks, or by having the thread that is reading the value of the variable join()
the thread in which the variable is written.
Edit: In response to your comment, a Future
has internal synchronization such that calling get() on a Future establishes a "happens before" relationship when the call returns, so that also achieves proper synchronization.
Upvotes: 5
Reputation: 38910
You can chose one of available options to achieve the same purpose.
volatile
to force all threads to get latest value of the variable from main memory.synchronization
to guard critical dataLock
APIAtomic
variablesRefer to this documentation page on high level concurrency constructs.
Have a look at related SE questions:
Avoid synchronized(this) in Java?
What is the difference between atomic / volatile / synchronized?
Upvotes: 0
Reputation: 27115
No, you don't need volatile
...
is there a happens-before relationship enforced (without the volatile keyword)?
...but your code needs to do something to establish "happens-before."
There will be a happens-before relationship if (and only if) your code does something that the "Java Language Specification" (JLS) says will establish "happens-before."
What about the scenario where Thread A changes the value of a field, and Thread B evaluates it after Thread A is guaranteed to have completed?
Depends on what you mean by "guaranteed." If "guaranteed" means, "established happens-before," then your code will work as expected.
One way you can guarantee it is for thread B to call threadA.join()
. The JLS guarantees that if thread B calls threadA.join()
, then everything thread A did must "happen before" the join()
call returns.
You do not need any of the shared variables to be volatile
if thread B only accesses them after joining thread A.
Upvotes: 1