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.