Talk:Singleton pattern
From Wikipedia, the free encyclopedia
On the term 'Singleton' in wikipedia:
In computer programming, a singleton is a common design pattern. It refers to a class which is meant to be not freely instantiated, but have only a defined number of instances. See Singleton pattern. A singleton is also a variable that is only used once in a program, usually indicating a programming mistake. See singleton variable.
From the start of the term 'Singleton pattern':
In software engineering, the singleton design pattern is designed to restrict instantiation of a class to one (or a few) objects.
A casual observer might think these statements agree, but a defined number of instances could also be ZERO. If this is true, then the singleton class in ruby really is a singleton, if it has to have at least once instance, then the singleton class is not a singleton because it cannot have any instances. People keep calling this a metaclass in ruby, but the only real metaclass is Class according to the wikipedia definition of 'Metaclass' (a class who's instances are classes). Which statement is true about the singleton?
Okay, way too much information here. Tak, what is the point of all the comments, questions and answers? Wikipedia is an encyclopedia, not the repository of all information ever written about a subject. I think, 90% of the content here should be deleted -- it's just not appropriate for Wikipedia. -Frecklefoot
Question: Is it true that when the only reference to the singleton is in the instance itself Garbage Collector might collect it? In my test it didn't happend which doesn't mean it never happens.
- No, this is not true.
Question: Could someone include an example of how the Singleton is suppose to be used?
The Singleton pattern should never be used.
[edit] Java code and double-checked locking
Tfischer wrote that the Java code is "vulnerable to the double-checked locking anti-pattern".
The createInstance() method is "synchronized". My understanding of a synchronized method is that while one thread is in createInstance(), no other thread may enter any "synchronized" method, including createInstance(). Thus if getInstance() were also declared "synchronized", the double-checked locking issue would disappear.
Can anyone confirm this? Isn't this worth fixing?
[edit] PHP5 Example?
Is the PHP5 example necessary? Also, that section appears to have typos and mistakes (I don't think Bruce Perens authored PHP 5 Power Programming). I'm going to remove it for now because of this. Perhaps it can be re-added once these issues are dealt with. -Miknight
PHP5 Power Programming is a Bruce Perens title, although he is not the author of the book. You can see the PHP5 Singleton example at the Zend Site. -Jough
[edit] And this servers for...?
Well, that. What's the problem this pattern seeks to resolve? I would like to have an example (one which isn't just a global-variable-euphemism, please!). Better if one could see the way the example's problem is normally resolved and the flaws of doing it that way, and how the singleton pattern resolves thosǖe weaknesses... Thanks -- User:Euyyn
[edit] That's what links are for
Check the links at the bottom and you'll find descriptions of why/when this may be used. I don't think Wikipedia is the appropriate place to be assessing when and why something should be used. The examples are already borderline appropriate in my opinion. In fact, the only reason I even added the second example is frankly because the first one is a terrible example.
- Again, what's the problem this pattern seeks to resolve? The article says it's used when you only need one instance of a class. Well, that's not a problem in any programming language: Need one instance? Create one instance. No need for more? Create no more. So... is there really a problem this pattern resolves?
- If the answer's in the links,why isn't it in the article? I think it's more important for an encyclopedia to tell why is this needed than to show e.g. a posible implementation.
- --euyyn 02:23, 23 February 2006 (UTC)
[edit] RE: Java code and double-checked locking
I originally thought this was not double checked but it actually is. There are two methods, the first one does an unlocked check.
The question is why is there a bad example here. Why not add the correct lazy version?
[edit] RE: Java code and double-checked locking
Because I wasn't arrogant enough to presume what I know is right (even though it is) and delete the other example. I didn't bother with the lazy loading example because in most situations the cost of synchronization isn't worth lazy loading. In most cases the class isn't likely to be loaded until a getInstance() call happens anyway, effectively giving you lazy loading without synchronization. I should qualify that by saying most cases that I have observed, as I am in no position to say what is most often the case in all programs. - kablair aka hotshot 23 year old
[edit] RE: Java code and double-checked locking
I'm not sure how it's arrogant to state what you know to be true. I don't know how else we are supposed to communicate real knowledge to others (isn't that what Wikipedia is about?)
You are right, the static loaded version of the Singleton is almost always the best (most efficient and straightforward) way to do it in Java. However, it's not really a universal idiom and this page isn't particular to Java (to my knowledge.) It's helpful to sometimes point out how not to do something (in this case for example) but it's important to explain the correct way too.
[edit] RE: Java code and double-checked locking
Even if I believe it to be true it does not mean I'm right! Of course I was, but that's not the point. I changed the lazy-loaded solution to match what Bill Pugh suggests. It is simple, elegant, fast, easy to understand and completely thread-safe. DCL is actually fixed with the new memory model but it requires making the instance variable volatile which is slower than Pugh's idiom. I hope nobody objects to my having removed the solution I originally put up and changing the other one as well, it would just be too confusing having so many Java-specific solutions about a general pattern. Pugh's solution is "better" than either of the other two in that it requires neither synchronization nor sacrificing lazy instantiation, it just requires a little extra typing to create the holder.
[edit] RE: Java code and double-checked locking
The incorrect Java example is broken in that it is not incorrect. The object itself has no mutable state, and so does not suffer from threading issues.The second check is within the synchronized block, so there is no chance of more than once instance being created (per class-loader).
I suggest deleting rather than fixing the incorrect example. All it will be doing is confusing, and probably serving as a template for programmers who have not understood the issues.
BTW, very old versions of Sun's Java (like 1.0) did, apparently, garbage collect classes incorrectly. The spec now says that there is an implicit strong reference from class-loader instance to all of the classes it has loaded.
Sorry but it is incorrect. Please read any of the hundreds of references (one posted in this article) to understand why. Your assumption that it cannot create multiple instances is wrong.
> Sorry but it is incorrect. Please read any of the hundreds > of references (one posted in this article) to understand why. It is correct, as long as there is a second check inside the synchronized createInstance() method!
-
- Go to the Double-checked locking page if you want to argue this. If you feel the need to contradict the many reliable, expert sources explaining why the exact thing you claim works does not, that's the place to do it.
I have discussed this issue with some developers on my team: As far as we understand the issue (after reading Jeu George's blog as well as the article by Peter Haggar of IBM linked there), the reason for the double-checked locking to fail is *NOT* because the mechanism itself is at fault.
-
- The Java memory model does not allow this to be reliable. AS I understand it, if it did, it would severely limit JIT compilers ability to optimize bytecode.
In fact it seems to be a severe bug in *some* JIT compilers: memory is allocated and assigned to the reference *before* the constructor of the object is executed!
-
- As the JVM specification allows
The lvalue of an assignment is *changed* before the right side has fully been evaluated! For details please refer to the article written by Peter Haggar. The compilers affected by this issue will most likely be causing way more severe problems than this. String losing it's immutability (as mentioned by Haggar) being just one of the obvious ones. If this behaviour is actually violating the specs (which is something I am not going to research on for now), then the double checked locking is *working*.
-
- It doesn't violate the specs. The specs specifically allow this.
In case the author of the two lines quoted above does still not agree on this, I would humbly ask for a reply - possibly more detailed than the usual "wrong! rtfm!". Best Regards, Felix Ehlermann, Senior Developer, Jenomics GmbH
-
- Please read the double-checked locking page and the many sources explaining why double-checked locking does not work. In almost all cases you can use staticly initialized singletons or initialize using an inner class. The 1.5 memory model 'fixes' volatile so you can use that to fix double-checked locking but only on 1.5 and above. Read this http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html#dcl Dubwai 15:37, 23 June 2006 (UTC)
[edit] RE: Java code and double-checked locking
Are you guys talking about the double checked locking example which says:
utilizing the suggestion in the double-checked locking anti-pattern, the synchronized keyword ensures that only one thread can enter the createInstance() method at once.
public class Singleton { private static Singleton INSTANCE = null; // Private constructor suppresses private Singleton() {} //synchronized creator to defend against multi-threading issues private synchronized static void createInstance() { INSTANCE = new Singleton(); } public static Singleton getInstance() { if (INSTANCE == null) createInstance(); return INSTANCE; } }
?
I mean, that code is not correct, right? If two threads are concurrently accessing "getInstance()" (and getInstance has not been called at all), and they both access concurrently if(INSTANCE == null), they both will say "yeah, it's null".
Now, one of them will enter in "createInstance", while the other will be just blocked before createInstance (but after "if (INSTANCE == null)"). So, the first one will enter, will create a new instance of Singleton, and will return from the createInstance and return this instance, while the other thread will call (again) createInstance, and it will return a different instance.
Adding another "if(INSTANCE == null)" inside "createInstance" would stop this wrong behaviour.
No it would not. Please read any of the hundreds of references (one posted in this article) to understand why.
And, answering the first comment in this thread, removing the "if(INSTANCE == null)" condition in getInstance or adding "synchronized" to getInstance would work, but if many threads were accessing to "getInstance", they all would be blocking one each other unnecessarily (I think).
[edit] RE: Java code and double-checked locking
This is NOT double checked:
public class Singleton { private static Singleton INSTANCE = null; // Private constructor suppresses private Singleton() {} //synchronized creator to defend against multi-threading issues private synchronized static void createInstance() { INSTANCE = new Singleton(); } public static Singleton getInstance() { if (INSTANCE == null) createInstance(); return INSTANCE; } }
"Double checking" requires a "check if null" then "synchronize" then "Check if null, agian" then "create." Here is a double checked example:
public class Singleton { private static Singleton INSTANCE = null; // Private constructor suppresses private Singleton() {} //synchronized creator to defend against multi-threading issues private synchronized static void createInstance() { if (INSTANCE == null) INSTANCE = new Singleton(); } public static Singleton getInstance() { if (INSTANCE == null) createInstance(); return INSTANCE; } }
-
- You are right, the example was not double checked. I have added the second check to the incorrect example.
[edit] Clarifying the Singleton Article
While the Double Checked Locking (DCL) idiom works well in environments which have a well-defined memory barrier, DCL is generally accepted as an anti-pattern in Java because the Java Memory Model did not have such until JDK 5. While, as others have noted, DCL can be modified to work correctly in JDK 5 (or higher) environments, a better choice for the Java Singleton implementation is the Initilization On Demand Holder idiom. The Initialization On Demand Holder idiom works in all Java environments, it performs well, and is a simple pattern to implement. See the following pages for the details:
http://www.cs.wustl.edu/~schmidt/PDF/DC-Locking.pdf http://www.cs.umd.edu/~pugh/java/memoryModel/ http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html http://www.cs.umd.edu/~pugh/java/memoryModel/jsr-133-faq.html
To help the Singleton article focus what a Singleton is and how it can be correctly implemented, I recommend the removal of the discussion how a Singleton can be incorrectly implemented in Java. A citation to the Double Checked Locking Idiom could be included, perhaps as a neutral reference or as an anti-pattern reference, and the DCL article could discuss or link to the DCL anti-pattern common in Java.
Jan Nielsen 18:12, 2 July 2006 (UTC)
[edit] Reference to Initialization on Demand Holder Idiom Article
I have added a new article called Initialization on Demand Holder Idiom which describes the idiom and provides an example in Java. Unless there are objections, I will change this article by removing the discussion on how not to implement a singleton to focus this article on what a Singleton is and how to implement it correctly. If there are objections, please post them here ASAP.
Jan Nielsen 16:07, 5 July 2006 (UTC)
I have removed the "incorrect Java implementation".
Jan Nielsen 05:51, 13 November 2006 (UTC)
[edit] Problem with some of the code or comments
Section: 'C# (using IDisposable)'
Method: private void dispose(bool disposing)
private void dispose(bool disposing) {
// Check to see if Dispose has already been called. if (!this.disposed) { // If disposing equals true, dispose all managed // and unmanaged resources. if (disposing) { if (someStream != null) { someStream.Close(); } } // Call the appropriate methods to clean up // unmanaged resources here. // If disposing is false, // only the following code is executed. if (someComObject != null) { Marshal.ReleaseComObject(someComObject); } } disposed = true;
}
The comment 'Call the appropriate methods to clean up unmanaged resources here. If disposing is false
The code 'if (someComObject != null)' will ALWAYS be executed because the code is not with the if above.
[edit] Who deletes the instance in C++?
In the thread-safe C++ example the single instance is allocated with new. I do not see how the destructor would ever be called. Shouldn't the example us an auto_ptr or equivilant? —The preceding JohnCFemiani 15:45, 7 December 2006 (UTC)
- Done; thanks for catching that. I'm thinking that perhaps we should get rid of the C++ examples altogether. The first one is a clever hack, but the hack isn't relevant to the topic; and the second one is bug-prone, as we've just seen. Examples in an encyclopedia should be relevant and clearly bug-free. (See this proposal by me.) So if anyone wants to take the plunge, I won't object.
- Oh, and a technical note on the new
auto_ptr
example: The destructor forSingleton
doesn't need to exist, but if it does exist, it must be public. Otherwiseauto_ptr
won't be able to see it. At least, that's my (limited) understanding. --Quuxplusone 23:26, 6 December 2006 (UTC)
Personally, I think that it is helpful to see concrete examples of these things in a language I understand; perhaps they can be relegated to an 'appendix' section or something. It also seems that neither C++ example seems to actually control the "at most" aspect of a singleton. Since the constructors are not private one could create as many instances as one wished to. The template solution used here can not hide constructors; it can only make sure there is at least one global instance. JohnCFemiani 15:45, 7 December 2006 (UTC)
- In both cases, the constructors are protected, so the user can't create instances of the class willy-nilly. (See, that's the sort of nitty-gritty that distracts from the point of these examples!) --Quuxplusone 23:56, 7 December 2006 (UTC)
[edit] Meyers singleton
The non-thread-safe C++ example using the Curiously Recurring Template Pattern says that it's also known as the "Meyers Singleton" (after Scott Meyers, who apparently gave an implementation in More Effective C++). However, this Web-forum discussion is the only online source I can find for a "Meyers singleton" (other than Meyers' own website, which says he invented it but doesn't say what it is). And that forum discussion disagrees with our article — their "Meyers singleton" doesn't use the CRTP at all! Therefore, I have restored the {{citation needed}} marker to that claim, and if it can't be verified in a few weeks, I'm just going to be WP:BOLD and delete the "Meyers" stuff. Someone who owns More Effective C++ might look it up. --Quuxplusone 04:09, 9 January 2007 (UTC)
- I've just removed the entire CRTP C++ example from the list of examples, thus making this question moot. As I noted in the section right above this one, it's pretty much irrelevant anyway, and it's not thread- or exception-safe. So, it's gone. (I'm not sure the novelty of the Ruby example makes up for its pedagogical uselessness, either...) --Quuxplusone 05:38, 15 January 2007 (UTC)
[edit] About replacement of the class diagram
I changed the class diagram because the underlines (They mean "static") are very important information for this pattern. --Trashtoy 03:04, 24 February 2007 (UTC)
[edit] PHP Singleton without Class Static Variable
It's also possible to use a function static variable instead of a class static one in PHP, which keeps things tidier IMHO:
class Singleton { public static function getInstance() { static $instance; if (!$instance) $instance = new self; return $instance; } private function __construct() { /* Cannot create any more */ } private function __clone() { /* Cannot be cloned */ } // The rest of the class implementation goes here... } $instance = Singleton::getInstance();
Unfortunately there's currently no easy way to put this in a class that can be extended! (See comments of http://www.php.net/singleton for some ideas of ways around that limitation.)
--DaveJamesMiller 18:12, 4 March 2007 (UTC)
[edit] Global point of access for the singleton instance
In the Gang-Of-Four book, the singleton pattern is characterised by two requirements: one, restrict the instantiation of a class to one instance, and two, provide a global point of access to that instance. The article currently describes the first requirement but (as far as I can see) does not explicitly describe the second requirement. Is this intentional? — Tobias Bergemann 13:14, 5 March 2007 (UTC)