We all know the double check locking bug in Java right?
Noticed this issue in one of our static singleton constructors.
public static FXRateService getInstance() { if (fxRateService == null) { synchronized(FXRateService.class) { if (fxRateService == null) { fxRateService = new FXRateService(); } } } return fxRateService; }
This is a particular problem, if getInstance() is accessed by two threads, there is a chance that the FXRateService returned will be uninitialised. One of the known solution would be simple to create the service eagerly, via a static declaration statement.
My boss however, from a .net background came up with another solution involving adding an additional boolean to signal the thread.
private static boolean ready = false; public static FXRateService getInstance() { if (!ready) { synchronized(FXRateService.class) { if (!ready) { fxRateService = new FXRateService(); ready = true; } } } return fxRateService; }
He argues that this way, the 2nd thread will always wait until the boolean becomes true before proceeding to the synchronized code. This seems to make sense at first glance, however due to the way Java Memory model works, it is still not correct.
Though the synchronized block guarantees only one thread will enter the block at one time, the order of execution can still be reordered by the compiler depending on the implementation of the JVM. It is entirely possible for ready == true before fxRateService is properly initialised.