Does the synchronize keyword need to be applied to each method of a class that implements the singleton pattern like this?
public class Singleton {
private Singleton(){}
public synchronized static Singleton getInstance()
{
if(instance == null)
instance = new Singleton ();
return instance;
}
public void DoA(){
}
}
Since Singletons don't expose a public constructor and the getInstance() method is synchronized, one does not need to synchronize method DoA and any other public methods exposed by the Singleton class.
Is this reasoning correct?
To make a singleton class thread safe, getInstance() method is made synchronized so that multiple threads can't access it simultaneously.
Without volatile the code doesn't work correctly with multiple threads. From Wikipedia's Double-checked locking: As of J2SE 5.0, this problem has been fixed. The volatile keyword now ensures that multiple threads handle the singleton instance correctly.
Is singleton thread safe? A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.
It's just like any other class. It may or may not need further synchronization.
Consider the following example:
public class Singleton {
private Singleton() {}
public synchronized static Singleton getInstance() { ... }
private int counter = 0;
public void addToCounter(int val) {
counter += val;
}
}
If the class is to be used from multiple threads, addToCounter()
has a race condition. One way to fix that is by making addToCounter()
synchronized:
public synchronized void addToCounter(int val) {
count += val;
}
There are other ways to fix the race condition, for example by using AtomicInteger
:
private final AtomicInteger counter = new AtomicInteger(0);
public void addToCounter(int val) {
counter.addAndGet(val);
}
Here, we've fixed the race condition without using synchronized
.
Well, the purpose of the Singleton class is that there is at most one instance of it and that all Threads can access that same object.
If you would not synchronize the getInstance
method the following could happen
Thread1 enters getInstance()
Thread2 enters getInstance()
Thread1 evaluates instance == null
to true
Thread2 evaluates instance == null
to true
Thread1 assigns instance
and returns
Thread2 reassigns instance = new Singleton()
and returns.
Now the threads both have a difference instance of the Singleton class which is what should have been prevented by this pattern.
Synchronizing prevents that both Threads can access the same block of code at the same time. So synchronization is needed in a multithreaded environment when you instantiate singleton classes.
Now assuming that multiple threads will attempt to access the Singletons methods at the same time synchronization might be necessary on those methods as well. Especially if they change data instead of only reading it this is true.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With