AfterWorkGuinness
AfterWorkGuinness

Reputation: 1850

Do I need the volatile keyword? (Java)

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

Answers (3)

Warren Dew
Warren Dew

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

Ravindra babu
Ravindra babu

Reputation: 38910

You can chose one of available options to achieve the same purpose.

  1. You can use volatile to force all threads to get latest value of the variable from main memory.
  2. You can use synchronization to guard critical data
  3. You can use Lock API
  4. You can use Atomic variables

Refer 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

Solomon Slow
Solomon Slow

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

Related Questions