- Feature Articles
- CodeSOD
- Error'd
-
Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
I think building singleton behaviour into the class itself is usually the wrong idea anyway - you're making an assumption about how that class will be used which often is irrelevant to how the class works.
I like to imagine someone might one day want to build a utility to sync 2 instances of the system by instantiating 2 complete copies of everything and shuffling data between them.
Admin
"Each new construction replaces the shared instance with a new one"
To me it looks like only the frist invocation of the constructor would do so
Admin
And it's almost always unnecessary. What's particularly egregious is the sheer volume of heroics that people expend on making sure it stays a singleton. Make one inside
main()
, pass around refrerences to it and move on to an actual real problem.Admin
The check for if _instance is null means it'll only set itself as the instance the first time it's constructed, not every time. This also means the doSomething method only runs if it's the first instance of the class, not last.
Admin
Since
GetInstance
is static, can't you callSystemMemorySettings.GetInstance
before callingSystemMemorySettings()
and get backnull
?Admin
They invented the new "multingleton" pattern. ROFL
Admin
If this is .net then spoiler, static assignments to members are thread safe.
This is a correct implementation of an eager singleton. Don't do this in other languages, because most guarantee thread-safety.
Now to make the thing lazy, things get tricky because there are three ways of to do concurrency: threading, parallelism and asynchronous calls. Parallelism is just a queued work item in a thread pool, so you handle it like regular threads but this is not true for asynchronous calls at all. Especially with asynchronous calls you will end up with an IDisposable factory and there's pretty much no way around this, but a factory that can do both would look like this:
Addendum 2025-04-09 09:10: Should be _lock?.Dispose() ofc, small typo.
Addendum 2025-04-09 09:12: And the factory methods should be static obviously (or better in their own factory type so that people dont access the private member directly).
Addendum 2025-04-09 09:13: Plus I forgot the await before WaitAsync - boy, writing code in the DailyWTF editor is hard haha
Admin
@MaxiTB ref
I suspect you're meant to write "... because most don't guarantee thread safety."
Everything about the posting tools here are difficult to do a good job with. Given that precision of expression is really pretty fundamental to our overall topic, the lacak of true editing capability is lotsa dumb and lotsa disappointing.
At least for those of us trying to say something more substantial than: "Hurr durr - lookit the idjit code!"
Addendum 2025-04-09 11:12: And of course I have an uncorrectable word error too. My "I suspect you're ..." should be "I suspect you ...". Gaah!!
Admin
A not-quite-so-insane interpretation:
There's a master object that works. For some reason other copies exist, probably to do some subset of the work of the master copy; maybe even just for type compatibility. This is a guard against somebody treating a copy as the master.
Admin
"For some reason other copies exist" Annual Report_Final.doc
Annual Report_Final (edited).doc Revised Annual Report (Final Edited).doc Revised Annual Report_Final v2.doc . .
Admin
Jail time
Admin
I think the word you're looking for is "deceptively easy to understand"...
Here's how to deal with singletons in Java:
Don't. (For all the reasons in this tread...)
Ok, if you insist: public enum MySingleton { INSTANCE; ... }
I've only really used them when I have very separate system parts that interact with... let's call it a memory only data set (table? database?), for lack of a better word. I.e. if you have more than one, you're going to get funky behavior.
Though, in most cases you want something like a "session" class or root manager or whatever it's called. That you pass around all over the place... (and that all service classes holds a copy of and can return). Sometimes you also want some kind of pool behavior... it all depends on what problem you're trying to solve really... possibly a pool in the session :D
Admin
Ha, yeah, but I reach the post character limited, so no more "edits" possible :-) Should have wait with this one till I was home at my PC instead of trying to get it right on my phone.
Admin
Obligatory: "Singletons Are Pathological Liars" https://testing.googleblog.com/2008/08/by-miko-hevery-so-you-join-new-project.html
Dropping a singleton into the programming language namespace for all comers is an anti-pattern. Enforcing singularity within the class itself, by any means, is an anti-pattern. Singularity is an extrinsic policy to be enforced by the application's startup code.
Admin
I think you could simply use a staticly-constructed
Lazy<Test>
with the appropriate thread-safety requirement.Admin
Ah, good ol' lazy. That takes me back when I recommended it on StackOverflow ... decades ago? Time flies by.
For those not familiar with .net history, Lazy<T> comes from a time when Microsoft tried to position .net as super generic and idiot-proof. The class is a text book example of over engineering and how that doesn't age well with time. It popped up in a time where asynchronous concurrency was in it's first iteration like on the Stream class and even parallel concurrency was not a thing yet (so using the thread pool in unified way with Task<T>).
So it comes with obvious shortcomings:
It doesn't work well with custom synchronization contexts, so in an asynchronous scenario it should be obviously be avoid like the plague to avoid application halting deadlocks.
As mentioned before the default configuration is super bloated; and while it now works in a parallel context and is no longer prone to block the thread pool thread, it's highly inefficient for mentioned historical reasons (as is everything that tries to be super generic and idiot proof).
And finally, it comes with it's own issue especially how exceptions are handled and how you have to prepare and use the created objects, especially when you want to make sure that there is not deadlocking in an parallel context.
TL;DR: Lazy<T> was neat 20 years ago, but it has long outlived it usefulness. That's pretty much why I haven't seen it in any reputable project in the last decade and obviously since .net core MS themselves recommend not using it for the mentioned reasons above. If you don't use it in an asynchronous context, at least the class should be fine in most cases and safe to use - that's pretty much the only positive that comes to mind; it's not a BinarySerializer.
Admin
Getting a Singleton implementation that much wrong is actually a feat in itself.
Admin
Ah, the enum implementation, the favorite of body-shop consultancy interviewers.
If someone break a singleton with reflection, I say the consequences are on them for doing dumb things.
Admin
Singletons are actually really useful, particularly in old codebases where testing was regarded as "too expensive". Particularly, you'll find that e.g. a connection to a server is a singleton. An instance of an encryption class for encryption? Singleton. Something that handles extremely state-dependent data and needs to be cleaned up constantly? Singleton.
In fact, I'm convinced that academics who, after writing their 3rd thesis, go into programming by launching a startup, are immune to learning anything new at that point. They dont know what a singleton is - if you explain it to them, their head might explode. But they are extremely good at engineering solutions around half-implemented singletons, globals, and other wacky concepts, somehow, and if you touch it (because you now inherited it), and you try to "fix it", you'll actually end up breaking it and proving the old code owner's point: It works.
Maintainability is only important as long as you are young and unexperienced; once you're old and unexperienced, you can actually get away with just blaming unmaintainable code's shortcomings on others who are trying to fix it.
Admin
I’ve seen a slightly different pattern: A singleton is not a class with at most one instance but an instance with a very specific purpose, that should always and exclusively be used for that purpose. So I can have a translator class with three instances capable of translating German, French, or English text into another language.
iOS has a new feature that plays havoc with classical singletons: You can have what looks like multiple applications in the user interface, but implemented by a single executable. So instead of one singleton you might need one (not real singleton) per application in the UI and multiple in your executable.
Edit Admin
It's almost always a horrible mistake to program into the code of a class the assumption that it is a Singleton. But not always.
I've seen a truly good use for a true Singleton exactly once, and that was when dealing with communicating with the management plane of some hardware I was looking after. The management plane's firmware had a bug in it where if you sent two messages into it at a time, it could hard-crash and you'd need to take a road trip to the lights-out facility in the next state to press the physical button to reset it. So a Singleton communication controller was rather mandatory to save on having to spend half a day getting really annoyed with yourself. (Yes, this was a bug in the management layer, so you couldn't remote reset it; it was the part handling remote resets of the rest of the system, which was highly parallel.) And even then, as this was in Java, getting Spring to handle the details of Singleton-ness was entirely adequate; it didn't need to be baked in directly.