Making a POJO Thread Safe

Prashant Pandey :

Here's the class:

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

Here's the post-condition that I have come up with: The value returned by get() is equal to the value value set by set() or 0.

It is easy to see that the above post-condition will not always hold true. Take two threads A and B for instance. Suppose A sets value to 5 and B sets it to 8 after that. Doing a get() in thread A would return 8. It should have returned 5. It is a simple race condition situation.

How can I make this class thread safe? In the book Java: Concurrency in Practice, the authors have guarded value and both the methods on the same object. I fail to understand how this helps at all with the race condition. First of all, set() is not a compound action. So, why do we need to synchronise it? And even after that, the race condition does not disappear. As soon as the lock is released once a thread exits from the set() method, another thread can aquire the lock and set a new value. Doing a get() in the initial thread will return the new value, breaching the post-condition.

(I understand the the author is guarding the get()) for visibility stuff. But I am not sure how it eliminates the race condition.

Michael Berry :

First of all, set() is not a compound action. So, why do we need to synchronise it?

You're not synchronising the set() in its own right, you're synchronising both the get() and set() methods against the same object (assuming you make both these methods synchronised.)

If you didn't do this, and the value variable isn't marked as volatile, then you can't guarantee that a thread will see the correct value because of per-thread caching. (Thread a could update it to 5, then thread b could still potentially see 8 even after thread a has updated it. That's what's meant by lack of thread safety in this context.)

You're correct that all reference assignments are atomic, so there's no worry about a corrupt reference in this scenario.

And even after that, the race condition does not disappear. As soon as the lock is released once a thread exits from the set() method, another thread can aquire the lock and set a new value.

New threads setting new values (or new code setting new values) isn't an issue at all in terms of thread safety - that's designed, and expected. The issue is if the results are inconsistent, or specifically if multiple threads are able to concurrently view the object in an inconsistent state.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=107120&siteId=1