I have a code snippet that I don't understand I will highlight the bit that confused me.
private static final Object lock = new Object();
private static volatile YourObject instance;
public static YourObject getInstance() {
YourObject r = instance; // <---------- This bit, why do we assign it here ?
if (r == null) {
synchronized (lock) { // What is the benefit of this lock in here
r = instance; // assuming instance is null which will pass the first if ( r == null, what do we assign it again ?? I don't get the idea of this step at all.
if (r == null) {
r = new YourObject();
instance = r;
}
}
}
return r;
}
I have seen https://www.journaldev.com/1377/java-singleton-design-pattern-best-practices-examples but there implementation looks like this, which doesn't have two assignments.
public static ThreadSafeSingleton getInstanceUsingDoubleLocking(){
if(instance == null){
synchronized (ThreadSafeSingleton.class) {
if(instance == null){
instance = new ThreadSafeSingleton();
}
}
}
return instance;
}
YourObject r = instance; // <---------- This bit, why do we assign it here ?
It is easier to reason about local variables, which you really want here. Also there is overhead in reading volatile
variables that may not be merged by the optimiser.
synchronized (lock) { // What is the benefit of this lock in here
This is the lock that prevents multiple threads creating and assigning different instances of YourObject
simultaneously.
r = instance; // assuming instance is null which will pass the first if ( r == null, what do we assign it again ?? I don't get the idea of this step at all.
instance
may have changed between the first read for the null
check and the lock being successfully acquired.
Anyway, don't use double-checked locking - it's very confusing and there's probably better ways.