Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronization on immutable objects (in java)

Code snippet - 1

class RequestObject implements Runnable
{
    private static Integer nRequests = 0;

    @Override
    public void run()
    {       
        synchronized (nRequests)
        {
            nRequests++;
        }
    }
}

Code snippet - 2

public class Racer implements Runnable
{
    public static Boolean won = false;    

    @Override
    public void run()
    {
        synchronized (won)
        {
            if (!won)
            won = true;
        }
    }        
}

I was having a race condition with the first code snippet. I understood that this was because I was obtaining a lock on an immutable object(of type Integer).

I have written a second code snippet which is again impervious to 'Boolean' being immutable. But this works(no race condition is displayed in an output run). If I have understood the solution to my previous question properly the below is is one possible way in which things can go wrong

  1. Thread 1 gets a lock on an object(say A) pointed by won
  2. Thread 2 tries to now get a lock on the object pointed to by won and gets in the wait queue for A
  3. Thread 1 goes into the synchronized block, verifies that A is false and creates a new object(say B) by saying won = true(A thinks it won the race).
  4. 'won' now points to B. Thread 1 releases the lock on object A(no longer pointed to by won)
  5. Now, thread-2 which was in the wait queue of object A gets woken up and gets a lock on object A which is still false(immutably so). It now goes into the synchronized block and assumes that it has also won, which is not correct.

Why is the second code snippet working fine all the time??

like image 731
Abhijith Madhav Avatar asked Aug 04 '13 09:08

Abhijith Madhav


People also ask

Are immutable object synchronized?

Since immutable object's state doesn't change, they can be used in concurrent programming without any need for synchronization.

Is immutable classes require synchronization?

Immutable objects are inherently thread-safe. They do not require synchronization.

Is immutable classes require no synchronization?

Immutable classes make sure that values are not changed in the middle of an operation without using synchronized blocks. By avoiding synchronization blocks, you avoid deadlocks. And since you are always working with an unchangeable consistent state, you avoid race conditions.

Why should you avoid using Java's synchronized statement on an immutable object such as an integer?

That's because each thread changes the reference to the object that is to be locked. In order to synchronize properly, all of the threads need to lock the same object; e.g.


2 Answers

    synchronized (won)
    {
        if (!won)
        won = true;
    }

Here you have a transient race condition which you don't notice because it goes away after the first execution of the run method. After that the won variable constantly points to the same instance of Boolean representing true, which thus serves properly as a mutex lock.

This is not to say that you should ever write such code in real projects. All lock objects should be assigned to final variables to make sure they never change.

like image 187
Marko Topolnik Avatar answered Oct 01 '22 02:10

Marko Topolnik


Whether or not an object is immutable has nothing to do with whether it's suitable as lock object in a synchronized statement. It is important, however, that the same object be used by all threads entering the same set of critical regions (hence it may be wise to make the object reference final), but the object itself can be modified without affecting it's "lockiness". Additionally, two (or more) different synchronized statements can use different reference variables and still be mutually exclusive, so long as the different reference variables all refer to the same object.

In the above examples the code in the critical region replaces one object with another, and that is a problem. The lock is on the object, not the reference, so changing the object is a no-no.

like image 41
Hot Licks Avatar answered Oct 01 '22 01:10

Hot Licks