Welcome to MSDN Blogs Sign in | Join | Help

D Melodic Minor Accidental

A conglomeration of random thoughts on C#, .NET, OOP, and working at Microsoft

Syndication

Other Sites

Singleton Pattern

In the beginning, there was...

the singleton

Everything's got to start somewhere.  Just like there's only one object type to “rule them all”, the singleton represents cases where there's only one.

A pair of examples are the TextWriter instances that represents Standard Out and Standard Error.  You only need one instance for each of those, for your entire program.  It makes sense for all the code in your program, all the threads, all of ___(insert something here)_____, to share.  Since there's only one for the entire process, then you might as well represent it that way in your library or codebase.

Like the proverbial skinning of the cat, there are a bunch of ways to do this.  Here's a common one, say our type is Foo.

class Foo {

      // change the default constructor to private

      private Foo() { }

 

      public static readonly Foo Only = new Foo();

 

      public object DoFunctionality();

}

The above method is short and simple.  Here are the important things to take away:
(1) no public constructors: The point is to share instances, not to let people create their own.  The lack of public constructors indicates to developers that this is not your “run of the mill” type.
(2) immutable, immutable, immutable! nine times out of ten you don't want anything you do to this object to affect other code, threads, etc., in some inadvertent manner.  Another word for this is to make your type a functional type (no new ideas to functional programmers, who are used to dealing with singletons all the time). 

A more common thing that people will find in the .NET libraries is this implementation:

class Foo {

      // change the default constructor to private

      private Foo() { }

 

      private static readonly Foo sharedOnly = new Foo();

     

      public static Foo Only {

            get { return sharedOnly; }

      }

 

      public object DoFunctionality();

}

It hides the shared instance of Foo behind a property.  Library developers may choose this implementation since allows them to decide later exactly how to return their singleton instance.  In fact, in the gang of four design patterns book, the template they outlined is more similar to this, since their examples are in C++.

Another point to take in mind in regards to hiding your instance behind a property (or a method call) is that the compiler can no longer prove that two different accesses will always return the same instance of the object.  It's then up to users of this type to trust the implementation, but then again, it's another possible “bug” if your design explicitly wants only ONE instance.

Yet another common thing to do, if you've decided to abstract out the singleton behind a property is to delay its creation until needed, like so:

class Foo {

      // change the default constructor to private

      private Foo() { }

 

      private static Foo sharedOnly = null;

     

      public static Foo Only {

            get {

                  return (sharedOnly != null) ? sharedOnly :

                        (sharedOnly = new Foo());

            }

      }

 

      public object DoFunctionality();

}

Some people may not like the ternary (? :) expression, or the assignment used as an expression, but I think it's perfectly legit in something this simple.  What you'll notice changed is the removal of the readonly attribute, since you're instantiating on demand.  Although you're arguably gaining since you don't instantiate objects that you don't need for sure, you're also still opening yourself up for bugs by removing the readonly attribute (such as accidentally setting that field).

 

If you don't care about getting back the exact same instance, you may wish to statically refer to something similar to the lazy loader posted to JayBaz's blog, written by Cyrus, before he got his own blog.  But stay tuned to why I think IOptional<T> should be implemented differently.  It's been a little over the 48 hours Cyrus promised me to write this all up, but I've since then gotten an extension until morning :-P.

Others may point out that using either of the examples that employ the use of properties may slow down the program since you're actually executing code whenever you reference a property -- but this is usually trivial overhead, and one can probably assume that the JIT will optimize out the function call.

I bet you're probably thinking that I'm beating a dead horse, but I wanted to make sure to cover a lot of possible design choices and the pros and cons of each.  Next concept in the slate: unions.

Published Thursday, May 20, 2004 11:50 PM by TheoY

Filed under:

Comments

# Coming up: Design Patterns @ Friday, May 21, 2004 2:56 AM

More .NET Yumminess

# re: Singleton Pattern @ Friday, May 21, 2004 12:15 AM

Oy, less than half an hour and Cyrus brings up that the third singleton example isn't threadsafe.

I wholeheartedly admit it's true. If you want to, you can create a private static lock object that you have to acquire before you even test if the sharedOnly field is null or not (and retain it until you've finished assigning).

I'll add to my list of caveats (http://blogs.msdn.com/theoy/archive/0001/01/01/136483.aspx) that most of the examples aren't threadsafe, for the sake of simplicity. However, due to the shared nature of singletons, I really have no excuse. I'll tack on a threadsafe version for completeness.

Theo Yaung

# re: Singleton Pattern @ Friday, May 21, 2004 2:02 AM

Please can you guys comment on this article:

http://www.yoda.arachsys.com/csharp/singleton.html

It deals with a number of singleton implementations, some thread-safe, some not, in C#.

Andrew

# re: Singleton Pattern @ Friday, May 21, 2004 2:18 AM

How about using a Mutex as the locking object? I'm not sure how well this will turn out in the comments, but here goes:

class T
{
private static T instance;

private T() {} // Hide the .ctor

public static T Init()
{
if(instance == null) {
Mutex m = new Mutex();
m.WaitOne();

if(instance == null)
instance = new T();

m.Close();
}
}
}

IIRC, the pattern I'm using the Init() method is the double-check locking pattern. That should be thread-safe :)

Neil Cowburn

# re: Singleton Pattern @ Friday, May 21, 2004 2:20 AM

Andrew: That looks very well written. The author addresses the major issues (locking and the .net memory model) that tends to trip up most people. The last solution was one I'd never even considered before. He seems to get every right in it:

a) Thread safe
b) lazy
c) singleton even in the presense of serialization.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 2:30 AM

Scratch that. Not ssfe in the presense of serialization.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 2:33 AM

Neil: Your solution won't work as the mutex wouldn't be shared amongst both tthread. I.e. two threads can come in, both see that instance is equal to null. Then both will instantiate the mutex, successfully WaitOne on it and then both possible create the new T.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 2:37 AM

Andrew, I agree with Cyrus except for point (c)... actually, we just had an IM discussion about it. He'll probably add another comment (since I don't like the idea of deleting comments unless they're spam).

I've got a code sample coming up that combines the fifth example from your article with some code for serialization correctness.

In addition, I think Cyrus has a post in the works to refactor using his lazy loader, in case the same instance isn't needed each time.

Neil, I believe the .NET memory model creates some problems with the double-check locking pattern.

Theo Yaung

# re: Singleton Pattern @ Friday, May 21, 2004 2:39 AM

Neil: there are also issues with the double null checking pattern with the .net memory model. This is especially apperant on itanium which has much more flexible memory model.

For example, in the above case you could get the following:

Thread 1 enters, see instance is null
Gets the lock
Sees instance is null
instantiates a new T and assigns to instance.

Thread 2 enters sees that instance is not null
returns the instance.

Now that seems fine _except_ the instantiation of T is not gaunranteed to have finished. Specifically, the writing of T over instance might happen _before_ T's constructor writes all its fields.

Scary stuff hunh!

You'll need a call to MemoryBarrier in order to fix that. Or you can not do the double instance checkin.

See the 3rd example on this page:
http://www.yoda.arachsys.com/csharp/singleton.html

For more info.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 2:41 AM

Neil: I highly recommend the blogs Chris Brumme has done:

http://blogs.msdn.com/cbrumme and
http://blogs.gotdotnet.com/cbrumme/

For some very in depth information on these issues.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 2:50 AM

Thanks, guys. Interesting stuff!

Neil

# re: Singleton Pattern @ Friday, May 21, 2004 2:51 AM

I was under the impression that the WaitOne on the Mutex would block execution until the waiting thread got a lock, or at least that's what I was lead to believe.

Neil

# re: Singleton Pattern @ Friday, May 21, 2004 2:58 AM

Neil: You'd need a static instance of the Mutex so that it would be shared across all threads trying to access it. As it is each thread would get their own frshly initialized mutex and would obtain it on the WaitOne call without a problem.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 3:48 AM

Thanks for the interesting and lively discussion :)

Cyrus / Theo, would either of you be able to suggest, with what has been discussed so far in mind, a singleton implementation optimised for access from multiple threads without any laziness? I'd be interested to see your suggestions.

Cyrus: Thanks for the links to Chris Brumme's blogs - Friday's weren't meant for working, reading however... ;-)

Andrew


Andrew

# re: Singleton Pattern @ Friday, May 21, 2004 3:51 AM

Andrew: do you want to see one that is resiliant even in the presense of serialization?

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 4:32 AM

I wouldn't mind seeing both, but one without serialisation support is what i really want to see.

thanks!

Andrew

# re: Singleton Pattern @ Friday, May 21, 2004 4:36 AM

Andrew: I would say the simplest version that has the following properties:

a) Safe amongst multiple threads
b) Not lazy
c) Not safe in the presense of serialization

would be:

public class Foo {
public static readonly Foo Instance = new Foo();

Foo() {}
}

There's only one instance of Foo that will ever be created (except for during serialization). It's thread safe. And it's not lazy.

Cyrus Najmabadi

# re: Singleton Pattern @ Friday, May 21, 2004 5:43 AM

Cyrus: thanks for that :)

Andrew

# re: Singleton Pattern @ Friday, May 21, 2004 8:20 AM

Thanks for the article. I've been reading Design Patterns, but it's nice to see examples in a language I use every day. I've also come across this site: http://www.dofactory.com/Patterns/Patterns.aspx They've run through and made examples (both theoretical and "real world") of most patterns in Design Patterns.

Scott Williams

# re: Singleton Pattern @ Friday, May 21, 2004 8:51 AM

Scott: that site is an absolute gem!

Andrew

# re: Singleton Pattern @ Friday, May 21, 2004 11:33 AM

Cyrus: Your latest singleton example is structurally equivalent to the first example covered in this blog post! :-P

(though you chose different identifiers)

Theo Yaung

# re: Singleton Pattern @ Friday, June 04, 2004 3:38 PM

:-P

Cyrus Najmabadi

New Comments to this post are disabled
Page view tracker