Double Checked Locking in Singleton
No, since you are obtaining lock on the SearchBox.class
, only one thread will enter the synchronized block at a time. So the first thread enters then finds searchBox
is null and creates it and then leaves the synchronized block, then the second thread enter the block then it finds that the searchBox
is not null because the first thread already created it so it will not create a new instance of searchBox
.
The double checked pattern is used to avoid obtaining the lock every time the code is executed. If the call are not happening together then the first condition will fail and the code execution will not execute the locking thus saving resources.
Why is volatile used in double checked locking
A good resource for understanding why volatile
is needed comes from the JCIP book. Wikipedia has a decent explanation of that material as well.
The real problem is that Thread A
may assign a memory space for instance
before it is finished constructing instance
. Thread B
will see that assignment and try to use it. This results in Thread B
failing because it is using a partially constructed version of instance
.
double check locking in singleton pattern
Jon Skeet explains this in detail.
Locks are expensive.
If the object already exists, there's no point in taking out a lock.
Thus, you have a first check outside the lock.
However, even if the object didn't exist before you took the look, another thread may have created it between the if
condition and the lock
statement.
Therefore, you need to check again inside the lock.
However, the best way to write a singleton is to use a static
constructor:
public sealed class Singleton
{
private Singleton()
{
}
public static Singleton Instance { get { return Nested.instance; } }
private class Nested
{
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Nested()
{
}
internal static readonly Singleton instance = new Singleton();
}
}
Potential problems in Double Checked locking pattern in Singleton class
I am a big fan of the following pattern for lazy-initialized singletons:
public final class CassandraAstyanaxConnection {
...
private static class ConnectionHolder {
public static CassandraAstyanaxConnection connection = new CassandraAstyanaxConnection()
}
public static CassandraAstyanaxConnection getInstance() {
return ConnectionHolder.connection;
}
...
}
why java double check lock singleton must use the volatile keyword?
a thread may assign the instance variable before the constuctor finishes
That's not actually true. The assignment is right there in the code example:
instance=new DoubleCheckSingleton()
Obviously, the thread that performs that assignment can not possibly do the assignment before the constructor call has returned.
The problem is, when two different threads are running on two different processors without any synchronization, they will not necessarily agree upon the order in which assignments happen. So, even though thread A assigned the fields of the new object (inside the new DoubleCheckSingleton()
call) before it assigned instance
, thread B potentially could see those assignments out-of-order. Thread B could see the assignment to instance
before it sees some of the other things that new DobuleCheckSingleton()
did.
Declaring instance
to be volatile
synchronizes the threads. volatile
guarantees that everything thread A did before it assigned a volatile
variable will become visible to thread B when thread B fetches the value of the volatile
variable.
Related Topics
Using Mockito with Multiple Calls to the Same Method with the Same Arguments
Any Way to Declare an Array In-Line
Subclassing a Java Builder Class
What's the Advantage of a Java Enum Versus a Class with Public Static Final Fields
Can Constructors Throw Exceptions in Java
Add Context Path to Spring Boot Application
Overriding VS Hiding Java - Confused
Quickest Way to Find Missing Number in an Array of Numbers
Print an Integer in Binary Format in Java
Field Required a Bean of Type That Could Not Be Found.' Error Spring Restful API Using Mongodb
How to Read File from End to Start (In Reverse Order) in Java
Date Format Mapping to JSON Jackson
How Is an Instance Initializer Different from a Constructor
Initialising Mock Objects - Mockito