B. Goetz in his JCIP in chapter 16.3 wrote this:
Initialization safety means that
SafeStatesin Listing 16.8 could be safely published even through unsafe lazy initialization or stashing a reference to aSafeStatesin a public static field with no synchroniation [...]
Code:
@ThreadSafe
public class SafeStates {
private final Map<String, String> states;
public SafeStates(){
states = new HashMap<String, String>();
states.put("alaska", "AK");
states.put("alabama", "AL");
...
states.put("wyoming", "WY");
}
public String getAbbreviation(String s){
return states.fet(s);
}
}
unsafe lazy initialization
@NotThreadSafe
public class UnsafeLazyInitialization{
private static Resource resource;
public static Resource getInstance(){
if(resource == null)
resource = new Resource();
return resource;
}
}
I don't understand why it is safe to publish object that way. The resource reference is not volatile, thus there's no happens-before between writing to it ( resource = new Resource() ) and subsequent readings from it even if Resource is immutable.
That way, any thread that did not initialize resource might observe a stale value of the resource.
The UnsafeLazyInitialization is unsafe because one thread may set value of the resource before constructor of Resource is fully completed, so another thread will pick a reference to a partly initialised object.
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