I am wondering what is the best approach for following situation:
Lets say, that we have some kind of factory MyUtilFactory
returning cached instances of MyUtil
class. Multiple instances of MyUtil
are holded in a static Map<String,MyUtil> utilsCache
.
And now, abstract flow for lazy creation should be as follows:
utilsCache
is empty, perform first initialization - load instances to static cache map.Now, step 1 and 4 needs to be synchronized, as initialization is time consuming and it would be executed multiple times, however it is required only for the first initialization of cache and instance.
It is easy to put everything in synchronized block(or even method) and there would be no problem at all, however I would like to avoid synchronization where it is not needed.
One approach would be something like that
if (!someObject.isInitialized()) { // check if it is ready without synchonization
synchronized (someObject) { // its not ready so lets synchronize from here
if (!someObject.isInitialized()) { //first thread will get the samo outcome, but other threads will not
performInitialization();
}
}
}
Now the point of repeating the condition in synchronized block, is to allow first thread to perfom initialization. Any subsequent threads will wait for the first one to complete initialization, and than condition in synchronized if statment will not be fulfilled. It can be done just like that and it works preatty well, but I don't think it is the best and the most elegant approach for such issue. My question is, how to do it "the right way"
Yes is the right way well known as double check locking read also
http://en.wikipedia.org/wiki/Double-checked_locking
there is a little problem with "someObject.isInitialized()": "someObject" must be volatile in java 6.
private volatile SomeObject someObject= null;
Read this article it is very usefull
http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With