anupamD
anupamD

Reputation: 952

How stale data is avoided using synchronized keyword?

In the book "Java Concurrency in Practice", under the section, 3.1.1 State data, there is a code

@NotThreadSafe
public class MutableInteger {
private int value;
public int  get() { return value; }
public void set(int value) { this.value = value; }
}

which is not thread safe,because:

if one thread calls set, other threads calling get may or may not see that update.

whereas using synchronized keyword on both set and get methods makes it "correct". How?

@ThreadSafe
public class SynchronizedInteger {
@GuardedBy("this") private int value;
public synchronized int get() { return value; }
public synchronized void set(int value) { this.value = value; }
}

Here too if value is 0, and Thread A has called set(2) while Thread B has called get(), B may get value 0 and then A will set it to 2...which previous code was already doing. So what benefit we got from synchronizing the code..

May be I am missing something, but please guide. Thank you

Upvotes: 0

Views: 282

Answers (3)

Zak
Zak

Reputation: 7078

It's all about the "Happens Before Relationship", as termed by the official Java documentation.

In your case of two synchronised getter & setter methods reading & writing the same instance variable respectively, it depends on the sequence of operations, ie, whether the getter or setter was called first.

This relationship is simply a guarantee that memory writes by one specific statement are visible to another specific statement.

Two actions can be ordered by a happens-before relationship. If one action happens-before another, then the first is visible to and ordered before the second.

Synchronisation is one of ways to achieve this consistency. Another one, in your particular case would be to make the variable as volatile.

From the official Java docs:

Using volatile variables reduces the risk of memory consistency errors, because any write to a volatile variable establishes a happens-before relationship with subsequent reads of that same variable. This means that changes to a volatile variable are always visible to other threads.

Upvotes: 0

When you use synchronized method you get the exclusive access to the object that is in "Race Condition" risks. In that case you get the exclusive access to the value. This goal is obtained because the synchronized method use semaphore.

Synchronized in Java Java Doc - Here you can find a good example.

From Java Doc: If count is an instance of SynchronizedCounter, then making these methods synchronized has two effects:

First,

it is not possible for two invocations of synchronized methods on the same object to interleave.

When one thread is executing a synchronized method for an object, all other threads that invoke synchronized methods for the same object block (suspend execution) until the first thread is done with the object.

Second, when a synchronized method exits, it automatically establishes a happens-before relationship with any subsequent invocation of a synchronized method for the same object. This guarantees that changes to the state of the object are visible to all threads.

Upvotes: 0

Joachim Sauer
Joachim Sauer

Reputation: 308001

The issue you fix this way is not that thread B executes the set immediately after A executes a get, that one will still return the "old" (well, technically correct at the time, but soon to be wrong) value.

The issue the synchronization fixes is that even if thread B wrote before thread A read, A could read an old value due to caching (most likely CPU caches, but this depends on the JVM implementation). A non-synchronized read from a non-volatile variable can use a cached value. In other words: the synchronized creates a read-barrier, which means "you have to re-read this value, even if you already have it in your CPU cache".

Note that for this specific case, simply adding volatile to value would have the same effect, but for more complex access patterns synchronized (or it's equivalence in newer APIs Lock) is necessary.

Upvotes: 3

Related Questions