Reputation: 147
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
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.
synchronized(A.class)
to update static variableRelated SE questions:
When to use AtomicReference in Java?
Difference between volatile and synchronized in Java
Upvotes: 0
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;
}
}
Upvotes: 5