Lets Consider the below Singleton code which uses Double Checked Locking
DoubleCheckLocking.java
public class DoubleCheckLocking
{
public static class SearchBox
{
private static volatile SearchBox searchBox;
//Private constructor
private SearchBox() {}
//Static method to get instance
public static SearchBox getInstance() {
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
return searchBox;
}
}
Lets dive deep into the code where Double Checking actually takes place
if (searchBox == null) { // first time lock
synchronized (SearchBox.class) {
if (searchBox == null) { // second time lock
searchBox = new SearchBox();
}
}
}
- Lets say we have two threads A and B and lets assume that atleast one of them reaches line 3 and observes searchBox == null is true.
- Two threads can not both be at line 3 at the same time because of the synchronized block. This is the key to understanding why double-checked locking works.
- So, it must the case that either A or B made it through synchronized first. Without loss of generality, say that that thread is A. Then, upon seeing searchBox == null is true, it will enter the body of the statement, and set searchBox to a new instance of SearchBox. It will then eventually exit the synchronized block.
- Now it will be B’s turn to enter: remember, B was blocked waiting for A to exit. Now when it enters the block, it will observe searchBox. But A will have left just having set searchBox to a non-null value.