Talk:Singleton pattern
This is the talk page for discussing improvements to the Singleton pattern article. This is not a forum for general discussion of the article's subject. |
Article policies
|
Find sources: Google (books · news · scholar · free images · WP refs) · FENS · JSTOR · TWL |
This article is rated C-class on Wikipedia's content assessment scale. It is of interest to the following WikiProjects: | ||||||||||||||||||||||||||||
|
Implementation
[edit](cur | prev) 08:24, 11 March 2013 71.198.23.121 (talk) . . (16,721 bytes) (-824) . . (Undid revision 527381493 by Nmondal (talk) This will break all singleton patterns , not just Bill Pugh's , this is a deviation from discussion.) (undo) Was removed, and I do not understand why. Also, please note, in a reflective language (language supporting reflection), it is impossible to implement Singleton! Why don't we put it up here may I ask? Nmondal (talk) 12:37, 13 February 2014 (UTC)
The following has gotten me confused:
- Another notable difference is that static member classes cannot implement an interface, unless that interface
- is simply a marker. So if the class has to realize a contract expressed by an interface, it really has to be a singleton
At least in Java, it seems perfectly okay for a static member class to implement an interface:
interface SomeInterface { public void run(); } class SomeClass { static class Something implements SomeInterface { public void run() { System.out.println("This totally works."); } } }
"Something" in the above code snippet is a "static member class" of "SomeClass", and it also implements an interface. This compiles with no errors. So can someone explain how a "static member class" cannot implement an interface? Mtbradle (talk) 16:19, 24 July 2013 (UTC)mtbradle
I was just wondering about a very similar thing, although my thought was "no, there are definately some languages that allow static member classes to implement interfaces, even if its only in one of those languages that also has metaclasses and other such over-the-top object oriented features." I totally agree that the statement as it stands is utterly bogus. AJMansfield (talk) 21:10, 19 November 2013 (UTC)
Terminology
[edit]On the term "Singleton" in wikipedia: Asad
- 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
Garbage Collection Reference
[edit]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.
Yes, the statement is true: For example, the following java program can demonstrate this:
public class Foo { public static void main(String[] args){ Foo myFoo = new Foo(); myFoo.selfReference = myFoo; PhantomReference<Foo> ref = new PhantomReference<>(myFoo); myFoo = null; System.gc(); System.out.println(ref.isEnqueued()); } Foo selfReference; }
If running the program ever prints true, then that proves that the instance of Foo that was constructed was enqueued for deletion. AJMansfield (talk) 21:24, 19 November 2013 (UTC)
- In a singleton, the reference would be a static variable, not an instance variable. In Java classloaders keep strong references to all static variables they've loaded. Leem02 (talk) 02:41, 2 October 2016 (UTC)
Example of Use?
[edit]Question: Could someone include an example of how the Singleton is suppose to be used?
- The Singleton pattern should never be used. - Unsigned by 80.80.22.6
- A website's Session is a good example of a Singleton.--Wynler | Talk 14:18, 12 October 2007 (UTC)
- It might be used for that, but if the application is generic for more than one web site and runs in the same process (e.g in mod_perl, mod_python etc), it wouldn't work, because then they would all have the same Session instance. Unless what you want is truly *global*, you are likely to regret using the singleton pattern later on. Asksol | Talk 16:25 13 March 2008 (GMT+1) —Preceding unsigned comment added by 213.236.208.22 (talk) 15:25, 13 March 2008 (UTC)
- A website's Session is a good example of a Singleton.--Wynler | Talk 14:18, 12 October 2007 (UTC)
C# example
[edit]if "(...) that is used to restrict instantiation of a class to one object" and in example generic constraint "new()" is used then anywhere from the code you will be able to call this public constructor (from definition of generic constraint).
- Single instance application (when you want have only one window of an application or service) is the most example of Singleton's concrete application.
Please fix this code or switch to Java or other language - do not spoof C# such "gems"
Lazy Loading
[edit]I fixed the implementation with a true lazy loading Singleton. Did it when was anonymous but hey. It's fixed. - Arch4ngel 19:38, 28 October 2007 (UTC)
- its worth fixing to me i care about it you dont have anything in it at all only i dont its my accomplishment my dream my hard work my blood sweat and tears . it makes me sick evil everyone that has there hand in the destruction and torment of hurting and terrorizing gang stocking gaslighting me pure evil nothing good will every come to any of them because no of them are human god will handle them all sad only for mr . 160.3.165.13 (talk) 12:21, 20 September 2023 (UTC)
Java code and double-checked locking
[edit]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?
PHP5 Example?
[edit]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
And this servers for...?
[edit]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
That's what links are for
[edit]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.
RE: Java code and double-checked locking
[edit]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?
RE: Java code and double-checked locking
[edit]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
RE: Java code and double-checked locking
[edit]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.
RE: Java code and double-checked locking
[edit]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.......
RE: Java code and double-checked locking
[edit]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)
RE: Java code and double-checked locking
[edit]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).
RE: Java code and double-checked locking
[edit]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.
- Optimized the java code not to contain excessive volatile read. This article lacks the most effective way to obtain singleton which is thread local storage since it doesn't include memory barrier (or helper class that takes perm-gem space). —Preceding unsigned comment added by Bestsss (talk) 23:33, 25 December 2008 (UTC)
- Double checking is not a good way to implement a lazy singleton, far too much code. try a private static inner class Holder holding a final instance that is initialized on class load (of the inner class) and return that, and leave the rest to the java vm...
public class Singleton { private static class Holder { private static final Singleton INSTANCE = new Singleton(); } // Private constructor suppresses private Singleton() {} public static Singleton getInstance() { return Holder.INSTANCE; } } — Preceding unsigned comment added by 83.231.170.196 (talk) 12:18, 16 July 2019 (UTC)
Clarifying the Singleton Article
[edit]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)
- Actually, I'd say the best way to implement it is via thread local storage (incl. ThreadLocal past java 1.4). Why: loading extra classes takes perm gem memory and involves extra IO operation + classloader sync (this is the very 1st time the singleton is created). Bestsss (talk) 23:40, 25 December 2008 (UTC)
Reference to Initialization on Demand Holder Idiom Article
[edit]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)
Problem with some of the code or comments
[edit]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.
Who deletes the instance in C++?
[edit]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)
- The word 'protected' seems to imply that the designer actually intends for people to extend the class, which means they would be creating instances beyond the designer's control. JohnCFemiani (talk) 18:28, 22 December 2007 (UTC)
The current "thread-safe" version isn't really thread-safe. Since the first pointer check isn't protected by the mutex, it's possible (on platforms where pointer access isn't atomic) that at the time of the test the pointer is half-written, and therefore neither null (causing the then-statement not to execute) nor valid (making the returned pointer point at some wrong location). Then the current thread might use the pointer before the other thread, which has started to write the pointer, has a chance to finish writing the pointer (and therefore make it valid again).
Moreover, it isn't standard conforming either, because at the point where the auto_ptr is insdtantiated, the class Singleton is still incomplete, and according to the C++ standard instantiating a standard library template on an incomplete type causes undefined behaviour. Specifically in the case of auto_ptr, if the auto_ptr destructor is instantiated before the class Singleton is complete, it will cause a delete on incomplete type, which is undefined if Singleton has a non-trivial destructor (i.e. either there's an explicitly written destructor, or it has any base class or member variable with non-trivial destructor, for example if any member is a std::string, a standard container or a smart pointer). --132.199.97.100 (talk) 14:28, 1 July 2008 (UTC)
Meyers singleton
[edit]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)
About replacement of the class diagram
[edit]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)
PHP Singleton without Class Static Variable
[edit]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)
Global point of access for the singleton instance
[edit]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)
nonsense
[edit]"Implementation
The singleton pattern is implemented by creating a class with a method that creates a new language has concurrent processing capabilities the method should be constructed to execute as a mutually exclusive operation."
The above does not seem to make any sense. I see an old edit that makes this nonsense change - the previous text does seem to make sense. Could someone who knows how change it back again - if the previous text is valid?
Davidmaxwaterman 04:01, 9 August 2007 (UTC)
Citations
[edit]Please add more inline citations. Shinobu 04:40, 2 September 2007 (UTC)
Singleton considered harmful?
[edit]I would suggest that this entry should contain some reference to the fact that the singleton is almost universally regarded as bad design.
Some minimal references for this point of view:
Use your singletons wisely —Preceding unsigned comment added by Swiftcoder (talk • contribs) 20:48, 11 November 2007 (UTC)
C++ and pthread_once?
[edit]Why does the example create mutexes instead of using pthread_once? Bpringlemeir (talk) 20:12, 14 January 2008 (UTC)
clone() method in java?
[edit]Something should be added regarding the need to overwrite the clone method in java —Preceding unsigned comment added by Lax4mike (talk • contribs) 16:14, 21 January 2008 (UTC)
Question: why static volatile is used and why not only static in java 1.5 example?
[edit]why is it that static volatile is used for singleton and why not only static in java 1.5 example? What difference does that make? —Preceding unsigned comment added by 210.210.79.19 (talk) 07:10, 19 February 2008 (UTC)
C++ Pthread example is not Thread save either!
[edit]This topic is in need of attention from an expert on the subject. The section or sections that need attention may be noted in a message below. |
Warning: despite the claim "This is the only truly thread-safe implementation of a lazy-initialization of a singleton." below, the use of std::auto_ptr means that destruction is not correctly synchronised with construction, and therefore rules this out. RFST (talk) 14:47, 9 May 2010 (UTC)
This exemple should not stay on wikipedia, because it is wrong. In C++ due the language standard, the compiler is allowed to reorder execution as long as the execution is consistent at the control point (e.g. the end of a block of execution). Here a compiler would commonly rearrange the construction of the object and assign the singleton to the return value before the singleton object is fully constructed. A thread that want to get the singleton at the same time, would therefore return the value of an object that hasn't been fully constructed yet. And because of optimization, there is no way you can guard against this in a portable manner.
Please if you wanna find out more about this read this excellent paper by Scott Meyer and Andrei Alexandrescu.
The only thread-safe and rather portable (on POSIX systems) solution of a Lazy-initialized singleton is the following one, WITHOUT DCL:
#include <pthread.h>
#include <memory>
#include <iostream>
// Skipped the Mutex and MutexLocker declarations
class Singleton
{
public:
static Singleton& Instance();
int example_data;
~Singleton() { }
protected:
Singleton(): example_data(42) { }
private:
static std::auto_ptr<Singleton> theSingleInstance;
static Mutex m;
};
Singleton& Singleton::Instance()
{
// Note the absence of the first `if', that would lead to an error otherwise.
MutexLocker obtain_lock(m);
if (theSingleInstance.get() == 0)
{
theSingleInstance.reset(new Singleton);
}
return *theSingleInstance;
}
std::auto_ptr<Singleton> Singleton::theSingleInstance;
Mutex Singleton::m;
int main()
{
std::cout << Singleton::Instance().example_data << std::endl;
return 0;
}
You will note that each time you access Singleton::Instance() this is very expensive because of the locking. Therefore your threads must use local storage caching, in the following fashion:
#include <singleton.h>
class Thread
{
// The thread loop
void run ()
{
// early getting and caching of the singleton instance
Singleton* singleton = Singleton::Instance();
// rest of the code
// from now on, use the singleton variable
action1(*singleton);
action2(*singleton);
// etc
}
};
This is the only truly thread-safe implementation of a lazy-initialization of a singleton. The other way, of course is not to use lazy-initialization and to create the singleton in the general scope of your program, before the main. This even remove the use of locks. But if your singleton is expensive to create, or rely on some resource, this is the only thread-safe way to go. The above, quite portable (on POSIX systems at least) and it should be provided in place of the current example. - Sylvain 192.54.144.229 (talk) 06:46, 30 April 2008 (UTC)
There are many subtle problems to implementing the singleton in C++. This article attempts to address some of them, and makes many erroneous claims while doing so. If the article is to maintain its current level of technical description, you should take into account:
1- The static initialization order fiasco. You're not guaranteed the order of construction of globals, namespace members, and static class members between translation units.
2- The static de-initialization order fiasco. (Thus telling the user to cache a copy of the returned pointer is problematic as well.) If you start destroying static storage objects, you run the risk of a static storage object A referencing another one B in its destructor after B's been destroyed.
3- Double checked locking is broken for numerous reasons. The reasons generally boil down to 3a- compiler reorderings 3b- hardware reorderings and other single core processor reasons 3c- the cache consistency problem for multiple core processors
4- I notice that the pthread example has the mutex declared as a static class member.
If we declare it as a global, namespace member, or static class member, we have the static initialization order fiasco. The mutex might not be constructed before its first use.
We also have to be concerned about concurrent initialization of the mutex. We have to construct the mutex in a single threaded environment. There is no way to thread-safe way to construct a mutex on first use (besides using another mutex).
The solution is to make the mutex instance here into its own singleton, an eager-initialized construct-on-first-use singleton. For example, something like:
/*assuming we can leak mutexes. If not, we have the static de-initialization order fiasco to worry about.*/ namespace { Mutex& getMutex() { static Mutex * m = new Mutex; return *m; } }
/*a simple thread-safe version*/ T& getSingleton() { Guard g(getMutex()); static T* t = new T; return *t; }
/*force the mutex instantiation to occur before main is called, thus presumably before someone creates a thread. If someone creates threads before main is called, all bets are off anyway. Do NOT do that (create threads before main is called).*/ namespace { struct ForceMutexInstantiation { ForceMutexInstantiation() {getMutex();} } instance; }
A slightly more advanced discussion would include memory barriers or thread local storage as faster implementations of the thread-safe lazy-initialized singleton.
-Josh —Preceding unsigned comment added by 12.108.188.134 (talk) 20:42, 23 September 2008 (UTC)
C++ (using pthreads)
[edit]This section has too many complications and does not provide a error free example, the memory is leaked., and we are associating Operating System specific things such as mutex, memory mapping etc., I think we must provide a simple example which will work irrespective of the Operating System, and irrespective of the primitives provided by the OS. I will try to provide a non-leaky Singleton example, and remove the current example, which is tied to OS and somewhat very confusing. Kindly review the changes. Thanks. — Nvineeth talk 17:54, 14 October 2008 (UTC)
This is the guy who made the massive changes which you erased.
I added back a disclaimer that the code is incorrect as written now. I agree that it was overly complicated, and I'm fine with this pseudo-code example. However, let us not mince words. The sample before your change was reasonably platform independent and correct. Your sample, while fine as a sample to illustrate a point, has many problems. I listed the problems, which you then erased.
Your sample does not work correctly when combined into a real program because of: 1- The static initialization order fiasco. 2- The static de-initialization order fiasco. 3- Delayed dynamic initialization of namespace scope objects. 4- Writing to std::cout is not mutex protected.
For example, the generally accepted solution to the static de-initialization order fiasco is to leak the singleton. This is perfectly fine and the preferred approach for any operating system will reclaim the resources of the singleton when the process dies (read: all operating systems for resources like memory, file handles, etc.). It is NOT an error to leak a singleton in most cases.
I suggest reading these links for a good refresher on the basic problems of implementing a thread-safe, lazy initialized singleton. (This are the links you previously erased from the main page.) http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12 http://www.aristeia.com/Papers/DDJ_Jul_Aug_2004_revised.pdf
In the first link, it describes how the simplest and best solution is to simply leak the singleton. Note that the first link is the closest thing there is to a C++ official FAQ; it's maintained by people associated with the C++ standard's committee.
Moreover, why remove the mutex guard class "Lock"? The commonly accepted C++ style is RAII, http://wiki.riteme.site/wiki/RAII. —Preceding unsigned comment added by 12.108.188.134 (talk) 00:30, 23 October 2008 (UTC)
- Hi, For the static initialization/deinitialization fiasco requires at least two global static vars, but in the example there is only one local static and in fact the current code is built on the lines of the solution for this problem,see Faq 10.13. I agree RAII is fine, but why unnecessarily create (and destroy) Lock objects, when one will do? Thanks. — Nvineeth talk 09:26, 23 October 2008 (UTC)
The entire purpose of the singleton is to ensure safe, single construction of an instance of a type. The sample is a well formed and well defined program. However, if this code is included verbatim in another program, it will not work. This is one of the purposes of a sample: posting a correct code snippet that you can use in a larger project, a criterion on which this sample fails.
1- The static initialization order fiasco is one of the major problems implementing a the singleton correctly, and thus a correct sample should include code to deal with this problem.
2- The static de-initialization fiasco is another major problem in implementing the singleton correctly for any real program. The accepted answer is to let it leak if you don't need the destructor called, which is true for most singletons I've seen.
3- An anal problem is the delay of the dynamic initialization of namespace scope objects. Most compilers do not delay it, but there is one which will optimize away unreferenced translation units. (I'm not sure exactly how it generates correct DLLs in that case, but I have been told by reliable people this is the case.) Thus technically the only guaranteed way to do a singleton is pthread_once or something similar, not the code you posted.
4- Printing to cout without mutex protection will also cause it to crash on some systems.
5- Also, you do not understand RAII. Here is a sample of the "C-style" approach:
{ mutexInstance.acquire(); //do stuff that needs to be atomic mutexInstance.release(); }
Here is the same code with RAII:
{ MutexGuard guard(mutexInstance); //do stuff that needs to be atomic }
RAII is preferred in C++ because: 1- Locality of concerns. Acquiring and releasing some resource are aspects of the same concern. Thus it should be as close together as possible. It lessens the chance for programmer bugs. In the "C-style" approach, you might have an early return or something where you forget to put mutexInstance.release(), probably causing your program to deadlock. 2- The RAII approach is exception-safe. The "C-style" will not release the lock if an exception is thrown without an explicit try + catch. (This is just a brief overview. Go read up on it from people who can explain it better than I.)
Also, RAII does not actually result in "extra objects being created and destroyed" per se. Any optimizing compiler will generate the same binary for the "C-style" and the RAII way (except the RAII binary will have a little extra code that also makes it exception safe. For all commercial compilers, this will not add any code on the normal execution path, resulting in basically no overhead compared to the "C-style" approach.) (Also, go read up on exceptions in C++. Exception handling in C++ is not free on some platforms, but even if it's one of the bad platforms, introducing another stack object won't affect performance.)
-Same guy, aka Josh, professional C++ and Java programmer. —Preceding unsigned comment added by 12.108.188.134 (talk) 16:31, 23 October 2008 (UTC)
- Hi josh, yes, RIAA is definitely better, I did not read the "static" Mutex part in the previous example correctly so thought that there was bug., but when I check the older version, its perfectly fine. So it should be added back. Regarding the static init/deinit order fiasco, I dont think its applicable here, because it depends on how the singleton is implemented, and the one in the example does not depend on other static objects, nor is it global. — Nvineeth talk 10:46, 24 October 2008 (UTC)
You're missing the point. This implementation uses a static storage object, thus if another object attempts to use this interface during static initialization, there's a 50 50 chance that the program will fail. The alternative is saying "You're only allowed to use this interface, the singleton, after the call to main and only before the main call exits", aka not during static initialization and static de-initialization.
As to whether this is applicable, it depends. Do you want a correct sample or just an incorrect pseudo-code example which illustrates the idea? If it's not correct, there should at least be a disclaimer saying "This is incorrect code and will not work if combined with a real code base. (Possibly listing the X reasons why.) The sample here is only to illustrate concept of a singleton." --Josh —Preceding unsigned comment added by 12.108.188.134 (talk) 19:33, 24 October 2008 (UTC)
Common uses section
[edit]I deleted this from the Common Uses section:
- Singletons behave differently depending on the lifetime of the virtual machine. While a software development kit may start a new virtual machine for every run which results in a new instance of the singleton being created, calls to a singleton e.g. within the virtual machine of an application server behave differently. There the virtual machine remains alive, therefore the instance of the singleton remains as well. Running the code again therefore can retrieve the "old" instance of the singleton which then may be contaminated with values in local fields which are the result of the first run.
because it is by no stretch of the imagination a Common Use, or any kind of Use. Come to that, neither is the point above it - but at least the point above it makes sense to the reader. This one does not: e.g. the reference to "the virtual machine", given that there's no reason to expect there to BE a virtual machine necessarily. I'm also not convinced that the point being made here is important enough or non-obvious enough to deserve to be in the article, which is why I didn't make the effort to find somewhere else in the article to put it. Educres (talk) 11:52, 29 October 2008 (UTC)
The solution of Bill Pugh
[edit]Someone has changed the contructor to protected, should be private instead.
CloneNotSupportedException
[edit]In Pugh's second Singleton class overriding clone() looks unnecessary to me. The example Singleton is derived from Object, which already does the job of throwing a CloneNotSupportedException. It only would be necessary if Singleton implements Cloneable
, but then normally you would not throw a CloneNotSupportedException.
On the other hand, if you derive from a class that supports clone(), attempt to throw a CloneNotSupportedException produces a compile time error.
If i am wrong, please provide a reference at least, where people can find out the reason for this approach.
—Preceding unsigned comment added by 194.113.148.55 (talk) 12:48, 27 April 2009 (UTC)
Objective C
[edit]Hi, long time user, first time contributor here. I think that the Obj-C sample code should be modified to what Apple recommends in their docs.
They have described their interpretation here: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaDesignPatterns/CocoaDesignPatterns.html#//apple_ref/doc/uid/TP40002974-CH6-SW66
And there is sample code here: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/CocoaObjects/CocoaObjects.html#//apple_ref/doc/uid/TP40002974-CH4-SW32
However, I dare not edit the entry out of the blue as I don't want to step on anyone's toe. —Preceding unsigned comment added by 130.225.195.131 (talk) 08:20, 24 March 2009 (UTC)
Singeton Destructor:
[edit]Can some one add something on how to destruct a singleton object? How/Why etc etc?? There is some discussion on this at "http://sourcemaking.com/design_patterns/to_kill_a_singleton"
Raoravikiran (talk) 09:03, 19 May 2009 (UTC)
Singleton Implementation
[edit]Isn't the following phrase a little bit too much oriented to a specific language ? "Another notable difference is that static member classes cannot implement an interface, unless that interface is simply a marker. So if the class has to realize a contract expressed by an interface, it really has to be a singleton." I think he is speaking about JAVA, because static members in some languages like C++ can inherit of a class only made of pure virtual method (which is an interface) and implement them through their class definition.
I think that it can be clearer to remove this part of the Implementation explanation, what do you think of that?
daminetreg 82.126.199.131 (talk) 14:59, 16 November 2009 (UTC)
Flash doesn't really support Singletons
[edit]It might be worth mentioning that Flash Actionscript doesn't really support true singletons (because the constructor of any class must always be public). There are many ways to emulate it, though, and the example on this page is just that, an example of ONE way. It is certainly not the DEFINITIVE way to do it (there being none). --61.194.119.130 (talk) 07:45, 7 December 2009 (UTC)
Javascript
[edit]Is it worth mentioning Javascript in the prototype section? Many Javascript kids don't understand that the nature of the language and might come here looking. Sj26 (talk) 06:50, 1 February 2010 (UTC)
Current C++ examples
[edit]They are currently toy examples, something you learn once in class to learn its problems to never do it again. The last time I fixed it, someone said it was too complex for an encyclopedia entry, but I would at least like the caveats posted.
- I once solved Fermat's Last Theorem on the back of an envelope, but I don't remember where I've put it. (Read: talk is cheap.) RFST (talk) 18:54, 21 April 2010 (UTC)
The non-thread-safe example is the Meyer's Singleton, except most competent people will tell you not to use it because of the static de-initialization order fiasco. http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.14 Preferably it should be changed to a pointer, and perhaps with a note summarizing the above link.
- I'm so glad for you that you are competent while other people aren't. Are you also competent enough to substitute a solution that works? RFST (talk) 18:54, 21 April 2010 (UTC)
The first thread-safe singleton is anything but. It's so bad I'm removing it.
- You vandal! RFST (talk) 18:54, 21 April 2010 (UTC)
1- There are two variables for the singleton, the function local static and the static class member. I'm not sure why the code is obfuscated as such.
- How is that an argument for "bad"? With the same logic one might deduce that you're just "dumb". Not saying you are, but you should provide better arguments than throwing around words like "competent" (implying others aren't) or "obfuscated". RFST (talk) 18:54, 21 April 2010 (UTC)
2- Then there's the no-op "if (true)" for no apparent reason, perhaps the result of a lazy edit, the same edit which warned of double checked locking. It also has other pieces which looks like it was a quick edit to make correct a (broken) double checked locking example.
- Again, maybe not apparent to you, but if you want to differentiate between "without test" and "with test", writing the first version as "if (true)" makes for a more compact difference. What's "lazy" and "quick" about that? RFST (talk) 18:54, 21 April 2010 (UTC)
3- Then we have the extraneous createInstance function. The code should just be in the getInstance function. No reason to have another function. Just more obfuscation. Especially bad that the createInstance function is public, easily accessible, and not documented "don't use!!".
- OK, this only makes sense to compare it with the non-thread-safe one, but to call this obfuscation is a bit much... You were definitely wrong about visibility, however: it's a private function. RFST (talk) 18:54, 21 April 2010 (UTC)
4- The example also suffers from the static de-initialization order fiasco, and should be fixed as well.
- True. It's even worse, for thread synchronisation reasons. You missed that, didn't you! RFST (talk) 18:54, 21 April 2010 (UTC)
5- It also suffers from the static initialization order fiasco on the namespace scope Mutex object. This is fine for POSIX systems where you can construct a mutex before runtime initialization via a const expr initializer, but win32 requires runtime initialization of its provided mutexes. This is a very complex and generally poorly understood topic. I suggest reading http://groups.google.com/group/comp.lang.c++/browse_thread/thread/dd7f3af258a800cd/ded6c1299bbf7776?#ded6c1299bbf7776 for a good discussion on the topic. —Preceding unsigned comment added by 12.108.188.134 (talk) 23:36, 12 March 2010 (UTC)
- Well duh, this is pseudo code where you should substitute whatever applies to the platform under consideration, so this is beside the point. RFST (talk) 18:54, 21 April 2010 (UTC)
The second thread-safe singleton is better, but still has the following problems:
1- static initialization order fiasco, which the comments dismiss as "a bit contrived". I'm beefing up the warning, as this is a real problem. Also note that the construction of the singleton is not thread-safe if accessed by multiple threads because of the static initialization order problem.
- Eager construction in unreliable order disqualifies it in most situations. It has no significant added value over a simple global variable. RFST (talk) 18:54, 21 April 2010 (UTC)
2- Still has static de-initialization order problems.
- So it's definitely a worse solution instead of a better one, or not even a solution at all. RFST (talk) 18:54, 21 April 2010 (UTC)
This is the same guy to which RFST "replied". When I read an encyclopedia entry which purports to be "An example of the singleton pattern implemented in C++", I expect it to be a correct implementation of the singleton pattern in C++, not an incorrect implementation nor an implementation in pseudo code. I'll get around to refixing the C++ section shortly.
Delphi example
[edit]The Delphi example needs the Assigned check in the shared destructor. If the instance is freed during runtime, an error will occur if the check is not there. Whoever removed it, please refrain from doing so again. —Preceding unsigned comment added by Freddy1990 (talk • contribs) 10:25, 3 April 2010 (UTC)
'Mathematical concept of a singleton'
[edit]The current version characterizes the singleton pattern as a means of 'implementing the mathematical concept' of a singleton. I won't change it, but perhaps someone more knowledgeable than I am should? A singleton set is an extremely general concept, and it's not clear to me that this design pattern 'implements' this notion any more than does a bag with exactly one apple in it, say. Obviously, there is a connection between the two notions, and there is a good reason why the term 'singleton' is used here, but it seems to me the set-theoretic concepts are simply helpful in describing the design pattern, not something the pattern is intended to model. So, as I say, perhaps someone could either clarify the writing in an appropriate way? (That is, either in a way that addresses my concern, or, if I'm misunderstanding something, in a way that will discourage this misunderstanding in the future.) Thanks. MJM74 (talk) 06:34, 28 July 2010 (UTC)
Article too complicated
[edit]I'm really confused at how this article got so bloated and complicated. Although I agree that as much detail should be given about the origin, concept and implementation of the Singleton pattern, I find that information about specific examples using the AbstractFactory pattern and the multiple language implementations should be removed. Wikipedia should not have 100 examples for each language for this simple pattern (if this were the case, this page would be even more unreadable than it is currently). I say simple because this is the first pattern I ever learned in classes (and I suspect it is common for everyone else too).
If it were up to me, this page would be 4-5 paragraphs, an example code in a strongly-typed, common programming language (i.e. Java) and the class diagram that is currently available. If people complain that there isn't 100 examples for each language, they should learn to program in that language before trying to use patterns in it.
If nobody opposes this, I might go and move the examples to another page for clarity's sake by the end of the week. — Preceding unsigned comment added by Fuzzyrichie (talk • contribs) 04:34, 15 December 2010 (UTC)
forget my comment - it's inadequate.
Singleton across a program or across a system? where to draw the line?
[edit]Lets take two singleton examples. On my 8bit Amstrad CPC running Symbos (awesome multiprogramming OS using the Z80s unprotected memory space), I write an application in C++ that has a singleton in it. But... it isn't a singleton from the 'system' point of view, it has 2 instances when I run 2 instances of the C application. Let's say the singleton was modified to be a true singleton (across the system), then there are legitimate uses of that, like creating an instance of a graphics subsystem within the C application and not having two subsystems that are out of wack by running multiple copies of the same program. Now, I know they are two examples, but the article says system or system-wide multiple times. Shouldn't the definition of singleton mean single instance within a defined scope? or something like that?
ZhuLien 116.240.194.132 (talk) 05:39, 4 April 2014 (UTC)
- It has to be "system" wide, where "system" is defined as the scope visible to the programmer. This is usually thus the "program" scope, but an OS or JVM coder might see the entire machine platform (or the Java platform).
- The reason is that Singletons have a function as well as merely being Singletons. If a programmer writes SingletonA, with function A() then this can't be replaced by another SingletonB, with a different function B() – Singletons have "identity" as well as merely the Singleton behaviour. This has two implications:
- There can be many Singletons at a time – the scope of mutual exclusion is to make SingletonA a Singleton (i.e. only one SingletonA at a time), but not to care if there is a SingletonB (also a Singleton, but a different Singleton) in existence.
- Secondly, something (even identical code for SingletonA) will only be a Singleton within its scope of implementation (usually one program, or multiple instances of that program). There is no point in having a Singleton that is shared between pieces of code that aren't "aware" of each other, such that they can interact in a defined fashion. Singletons not only have to be Singletons, they have to do something useful too!
- If there is a code library that implements SingletonA, then it's necessary that programs either (and most commonly) using it get their own scope for this Singleton. This can be within the same single-threaded program, or within a complex multi-threaded program. Sharing a Singleton between programs is much less common (it's just not needed so often) and is harder to implement. If two copies of the same program are started, these could either share or exclude their Singletons (offering the same function) - which is needed would depend on the application. Both are "true" Singletons, just different scope.
- Singletons have a poor reputation amongst coders. There's a lot of debate out there about them, much of it saying, "Don't use Singletons". In practice, many problems arise because the initial designer didn't consider just what the necessary scope for the Singleton task was, so the coder chose to implement the wrong one. Andy Dingley (talk) 11:54, 4 April 2014 (UTC)
"Wikipedia is not a list of examples"
[edit]A comment under the Example section says this:
- Wikipedia is not a list of examples. Do not add examples from your favorite programming language here; this page exists to explain the design pattern, not to show how it interacts with subtleties of every language under the sun. Feel free to add examples here: http://en.wikibooks.org/wiki/Computer_Science_Design_Patterns/Singleton
However, every single example in this section is all about the subtleties of implementing the singleton pattern in Java. We need two examples, and two examples only: one for lazy initialization and one for eager initialization. Everything else in this article is Java-specific cruft. I'll do the purge myself if no one objects or gets there before me. Hpesoj00 (talk) 15:51, 27 July 2016 (UTC)
- Too late. I purged. Less is more. It's a marked improvement if you ask me. Hpesoj00 (talk) 17:44, 27 July 2016 (UTC)
- The following comment was originally posted on my personal talk page. Hpesoj00 (talk) 05:57, 28 July 2016 (UTC)
- H - Please revert your last three changes to the Singleton page. You have effectively removed a wealth of information. In the future please stick to editing poker-related content. — Preceding unsigned comment added by 96.28.228.213 (talk) 21:36, 27 July 2016 (UTC)
- First, I don't appreciate the condescending remark. Please try to keep things WP:CIVIL. Second, please log in when you leave comments on my talk page so that I know who I'm talking to. Third, I did indeed remove a wealth of information, but it was information I feel has no place in this article. Indeed, the comment I quoted specifically says that the page should not showcase the subtleties of implementing the singleton pattern in specific languages. Everything I removed I believed to be Java-specific content, not directly applicable to all languages in which the singleton pattern can be applied. However, I appreciate that I perhaps did not give sufficient justification for my deletions:
- Lazy initialization (using double-checked locking) – Double-checked locking is specific synchronization method with its own article, beyond the scope of this article. There are better ways to achieve the same goal in other languages and, indeed, in Java (I have kept the superior example). Comments about bugs in J2SE 5.0, an ancient version of Java, are definitely out of place.
- Lazy initialization (using
synchronized
) – This is a good, concise example of the singleton pattern in Java, so I kept it.
- Lazy initialization (using
- Eager initialization – This is a good example which I used as the "default" implementation of the singleton pattern. However, two of the three listed advantages mention "class loading" and use of the
final
keyword, both Java-specific features. The third advantage mentions that it is not necessary to synchronize calls togetInstance
, which I removed to improve flow, because the issue of locking is now discussed in the "Lazy initialization" section, where it is required. Feel free to add this one advantage back into the prose if you feel it is necessary.
- Eager initialization – This is a good example which I used as the "default" implementation of the singleton pattern. However, two of the three listed advantages mention "class loading" and use of the
- Static block initialization – Needless to say, a Java-specific feature used to address the generic problem of exception handling, a discussion of which does not belong in this article.
- Initialization-on-demand holder idiom – To quote the section itself, "about the code issues underlying the Singleton pattern when implemented in Java". This article is not about the specific issues of implementing the singleton pattern in particular languages.
- The enum way – This implementation relies on the specific behaviour of Java enums. It is not a generic design that can be ported to all other relevant languages.
- Prototype-based singleton – This has nothing to do with the singleton pattern. It is just terminology specific to a class of programming languages which happens to use the word "singleton". If the topic is significant, it should have its own article. However, it just seems like jargon, so if anywhere it probably belongs in the article for prototype-based programming.
- Example of use with the abstract factory pattern – This is just an example of a class which uses a different pattern, which uses the singleton pattern as part of its design, plucked from the Java AWT. This is totally out of place. Perhaps I could see the value in a code example showing how to use the singleton pattern as part of the abstract factory pattern, but I would probably argue that it belongs in the article for the abstract factory pattern.
- I have restructured the article on the basis that Java is to be used as the demonstration language, and no other languages are to be used. I see that articles on other patterns actually have a section of "Examples" listing code examples in all sorts of languages. However, I think the approach I have taken (after reading the aforementioned comment) is superior, as it removes the scope for adding endless examples from all sorts of languages. Being Wikipedia, this is of course open to discussion.
- However, I believe that the removal of these additional examples was justified. Put it this way: if you want to list 101 ways to implement the singleton pattern in Java, I hope you don't mind me adding 101 ways to implement the singleton pattern in C++. Hpesoj00 (talk) 05:57, 28 July 2016 (UTC)
- I'm far from a wikipedia editor, but I'm going to argue here. I do understand the interest in removing language-specific details from a general article. I believe that at least one of the java examples has made this page a "canonical resource" for correct singleton implementation (for good or bad). Note http://stackoverflow.com/questions/6109896/singleton-pattern-bill-pughs-solution and the fact that this article is still the #3 result in a google search for "bill pugh singleton". From my perspective the "purge" has removed useful information from the encyclopedia; perhaps it should have been moved to another page instead? Or maybe this page could have handled a sub-section on Java? Also, regarding the comment on how the Bill Pugh example was flawed, if you believe that to be true, please describe why on the Double-checked locking page - I don't see anything about it there. RobI (talk) 22:44, 7 December 2016 (UTC)
- @RobI: Thanks for your feedback. I was mistaken in my assertion that double-checked locking was an inferior implementation, as it gives better performance than the naive implementation. I have re-added it as the sample for "lazy initialization". With regard to the initialization-on-demand holder idiom (a.k.a. the "Bill Pugh singleton"), as far as I can tell it was devised as an alternative to double-checked locking to work around bugs in Java's memory model back in the day. As far as I can tell, these bugs have long since been fixed, so I feel there is no reason to include an implementation that relies on the idiosyncrasies of the JVM in an article which should be as language-agnostic as possible. Please let me know if you still have any issues with the article as it stands. (p.s. Anyone is a Wikipedia editor. I don't claim any authority here. Please be WP:BOLD and go ahead with any edits that you feel will improve the article. The worst that can happen is your change gets reverted.) Hpesoj00 (talk) 03:32, 17 January 2017 (UTC)
External links modified
[edit]Hello fellow Wikipedians,
I have just modified one external link on Singleton pattern. Please take a moment to review my edit. If you have any questions, or need the bot to ignore the links, or the page altogether, please visit this simple FaQ for additional information. I made the following changes:
- Added archive https://web.archive.org/web/20131002003845/http://www.javaexperience.com/design-patterns-singleton-design-pattern/ to http://www.javaexperience.com/design-patterns-singleton-design-pattern/
When you have finished reviewing my changes, you may follow the instructions on the template below to fix any issues with the URLs.
This message was posted before February 2018. After February 2018, "External links modified" talk page sections are no longer generated or monitored by InternetArchiveBot. No special action is required regarding these talk page notices, other than regular verification using the archive tool instructions below. Editors have permission to delete these "External links modified" talk page sections if they want to de-clutter talk pages, but see the RfC before doing mass systematic removals. This message is updated dynamically through the template {{source check}}
(last update: 5 June 2024).
- If you have discovered URLs which were erroneously considered dead by the bot, you can report them with this tool.
- If you found an error with any archives or the URLs themselves, you can fix them with this tool.
Cheers.—InternetArchiveBot (Report bug) 06:47, 6 December 2017 (UTC)
This article needs rework
[edit]Hi All,
This article need a bit of rework. The existing Java example for lazy initialisation can be found in the article "Double-checked locking", as well as a much better example, as the current example here can be considered an anti-pattern. — Preceding unsigned comment added by 83.231.170.196 (talk) 13:44, 17 July 2019 (UTC)
- Yup. I made an effort a while back, but it seems everyone is eager to turn this article into a "List of singleton implementations". Feel free to make an edit yourself, though I've concluded it's probably futile. Hpesoj00 (talk) 15:01, 29 June 2020 (UTC)
Criticism
[edit]The Criticism section is full of imprecise information and based only on someone's opinion. Phrases such as "because a singleton can be accessed anywhere by anything without having to use any parameters" and "singletons are difficult to test because they carry global state for the duration of the program." are so wrong that I do not even know from where to start. There's a mix of different concepts and probably some language/own experience biases. A mark should be added to this section to warn about this. — Preceding unsigned comment added by 82.131.59.214 (talk) 17:06, 2 November 2021 (UTC)
- I don't see anything wrong with this. Actually I believe the article in its current form is misleading since at least in the Design Patterns book by the Gang of Four, global accessibility of the singleton object is part of the definition of the pattern, I think. Or perhaps I misunderstand what you're saying. —Tea2min (talk) 11:35, 3 November 2021 (UTC)
- Agreed. The article is about Gang of Four singletons, and a GoF singleton "provide[s] a global point of access" and is "itself responsible for keeping track of its sole instance." That's very different from, e.g., a singleton lifetime in a dependency injection framework, where the class can be a POCO and not know anything about how it's used. Eeskildsen (talk) 18:40, 8 April 2022 (UTC)