Talk:Initialization-on-demand holder idiom

message: From multiple comments on and off the JSR-166 list, the original implementation from Bill Pugh has been modified to reduce the scope of LazyHolder.something to either private or package and to make the field final.
Jan Nielsen 17:09, 19 July 2006 (UTC)
thread_title: Untitled

message: Actually, declaring throws Error (LinkageError or ExceptionInInitializerError) will be an absolute anti-pattern. Not such it's unchecked exception but Errors should not be part of the code an application developer takes care.
Another problem with the code is:   static final Something something = new Something(); -- this will never compile (it's not compilable right now) if the ctor throws a checked Exception (like IOException) non-checked once will effectively generate ExceptionInInitializerError. If you wish to deal w/ checked exceptions you need static{ } clinit. Even if ther 1st attempt succeeds to deal with IOException by eating, throwing, whatever. Any further calls to getInstance() will throw NoClassDefFoundError. Indeed, it can be caught again even the exception can be re-thrown via new IOException(...).initCause(firstException), the code becomes extremely cumbersome and disallows any other recovery.
Bestsss (talk) 01:02, 26 December 2008 (UTC)
thread_title:  ExceptionInInitializerError 

message: Please correct me if I am wrong - I suppose that the following singleton implementation (without holder):
public class Something
{
     private static final Something something = new Something();
     public static Something getInstance()
     {
         return something;
     }
}
is equivalent to the holder implementation if the following conditions are met:
the class Something does not contain other public static members than getInstance()
no exception can be thrown from the constructor
My reasoning:
in the absence of other public static members calling getInstance() is the only way to cause Something being initialized. So when the class is seen as a black box (only considering its interface), I cannot see any semantical difference between the holder and the simple implementation.
the holder implementation can catch the resulting ExceptionInInitializerError, which is not possible with the simple implementation
Right or wrong?—The preceding unsigned comment was added by 204.104.55.242 (talk • contribs) 14 November 2006.
: The difference is that in your code, the instance of Something will be create when the program starts. The version in this article only creates the instance if and when it is needed. No difference from the outside, but it improves performance. --Apoc2400 05:12, 16 November 2006 (UTC)
replies: text: Class.forName("pack.Singleton") (actually using resoveClass=true with the classloader, normally ClassLoader.loadClass(String) uses false) very successfully class <clinit>, thus the idiom is not quite useful. Also classloaders may decide to clinit classes (happens in managed environment, xml descriptors, etc). The problem with the idiom is that relies a public class not to be resolved until getInstance() is called for real. I, myself, would never recommend such an idiom. Bestsss (talk) 00:06, 26 December 2008 (UTC)
replies: text: It is very precisely specified when class initialization happens (Java® Language Specification, §12.4.1) and, of course, the rules are the same for the outer class and the nested class, so there is no real advantage, even for the hypothetical non-conforming JVM that initializes referenced classes eagerly, as the outer class contains a symbolic reference to the nested class. If the outer class is “pack.Singleton”, you could call Class.forName("pack.Singleton") (and get what you ask for) but you could also call Class.forName("pack.Singleton$InnerClass") as well, so the laziness is never bullet-proof… 92.227.93.218 (talk) 09:48, 15 May 2018 (UTC)
thread_title:  Singleton implementation without holder 

message: How is this idiom different from the following code using the synchronized keyword?
 public class Something
 {
     static final Something something;
     private Something() 
     {
     }
     
     public static synchronized Something getInstance()
     {
         if(!this.something){
             this.something = new Something();
         }
         return this.something;
     }
 }
--Apoc2400 05:26, 16 November 2006 (UTC)
thread_title:  Difference from synchronized keyword 

message: The article doesn't describe what happens if all references to the instance go out of scope. In some situations it may be desirable that the object be destroyed on garbage collection, while in other cases it is imperative that it stays alive. How would you handle both these cases in Java? I know how to do it in (refcounting) C++ (trivial) and VB (RtlMoveMemory). Can this distinction be made in Java? Of course, if all references and the class loader go out of scope the object would probably be destroyed; I don't think you can do anything about that, nor do I think it usually matters. And even if this wouldn't happen, you could use a weak reference (java.lang.ref) to force it to be destroyed if all other references go out of scope, no? Still learning Java, so please comment. Shinobu 04:13, 2 September 2007 (UTC)
replies: text: The instance will be garbage collected when all the classes loaded by the classloader have no live objects held by any thread stack trace, no references held by other classes loaded by some other classloader... and the loading classloader has no references either. This may happen only to a custom classloader, i.e. no bootstrap, no system classloader (-cp). Read about classes garbage collection. Yet, such discussion doesn't belong here.Bestsss (talk) 23:46, 25 December 2008 (UTC)
thread_title:  Garbage collection? 

message: The pattern described on this page will not work with all versions of JAVA.
In the java memory model from before JLS version 3 (before J2SE 1.5) while the final keyword prevents the field from being initialized twice it is not a memory barrier and as such does not protect from access reordering on multiprocessor machines (which may cause a thread to use an object after it has been allocated but before the constructor has run)
See JSR133 FAQ for more information.
217.108.170.8 (talk) 18:05, 10 March 2010 (UTC)
thread_title:  Java memory model problem