Matti
Matti

Reputation: 147

Should lock object be volatile (synchronized block, multiple instances of class)?

I have created three objects from class A. All of these three objects can update a value which is stored in private static volatile variable in class A. Updating this variable is done within a synchronized block with a certain criteria. I want to synchronize the block by using a lock-object.

So first the object are created in MainClass

A a1 = new A();
A a2 = new A();
A a3 = new A();

And after this the objects start to live their own lives. Here's a simplified example of my class A.

public class A{
    private static volatile String sharedVariable;
    Object lockObject = new Object();

    private void updateVariable(String newValue){
        //... some code
        synchronized(lockObject){
            //... code to check whether to update the value
            sharedVariable = newValue;
        }
    }

Should I declare lockObject as private static volatile, if I want the synchronized block to be synchronized with all instances and all threads of class A? If I use the class (this) to synchronize the block, will it accomplish the same thing?

I think that with the above code the all of the instances of class A create their own lockObject and synchronized with it. Therefore the synchronization would only happen with threads within each instance (a1, a2 and a3). Is this correct?

Upvotes: 4

Views: 2162

Answers (2)

Ravindra babu
Ravindra babu

Reputation: 38910

Object level lock is not suffice to guard class variables. You need class level lock.

volatile variable are meant for different purpose. It is useful when you update the value of variable in one thread and read the value of variable from many threads.

Have a look at below solutions.

  1. Use static final lock as proposed by Gurwinder Singh
  2. Use synchronized(A.class) to update static variable
  3. Use AtomicReference

Related SE questions:

When to use AtomicReference in Java?

Difference between volatile and synchronized in Java

Upvotes: 0

Gurwinder Singh
Gurwinder Singh

Reputation: 39477

What volatile gives is a happens-before guarantee that subsequent read in all threads will see the most recently written values.

The purpose of volatile and static doesn't mix here.

If you define the lock object to be an instance variable, then it'll be created for each instance of A, which is definitely not desired.

Since the object on which synchronized access is required is static, you need to create a static final lock object. final (although not necessary but a good practice) ensures that the lock object is visible and isn't changed at runtime and static make a single lock to access the object

public class A{
    private static volatile String sharedVariable;
    private static final Object lockObject = new Object();

    private void updateVariable(String newValue){
        //... some code
        synchronized(lockObject){
            //... code to check whether to update the value
            sharedVariable = newValue;
        }
    }

More on this:

Upvotes: 5

Related Questions