Re: Simple and fast Singleton pattern for ya.
From: Jon Skeet [C# MVP] (skeet_at_pobox.com)
Date: 02/10/04
- Next message: _: "Re: Writing to App.Config"
- Previous message: Peter Rilling: "Re: How can I enum the instance of forms?"
- In reply to: William Stacey: "Re: Simple and fast Singleton pattern for ya."
- Next in thread: William Stacey [MVP]: "Re: Simple and fast Singleton pattern for ya."
- Reply: William Stacey [MVP]: "Re: Simple and fast Singleton pattern for ya."
- Messages sorted by: [ date ] [ thread ]
Date: Tue, 10 Feb 2004 06:12:07 -0000
William Stacey <staceywREMOVE@mvps.org> wrote:
> Not exactly what happens here. This is not the same as the double checked
> issue. DCL uses an unsynchronized testing of the object reference.
But that's not the problem with DCL - it then uses a synchronized
testing of the object reference if it was null.
The problem with the DCL is that write-ordering isn't guaranteed unless
you've got a memory barrier, so the reference itself can be written
before object has finished initializing. I don't see anything in your
code to stop a second thread correctly seeing that a first thread is
initializing the object, and then waiting until that initialization is
finished.
> So the
> ref could be assigned by thread1 and then context switch, then thread2 could
> get that ref and try to use it before construction. This does not happen
> here because construction is completed before the interlock releases the
> lock. The actual creation is protected by a memory barrier using the
> "lock()". The assignment also creates a "write" barrier on the ref from
> doco I have seen.
Yes, you've got a write memory barrier. You don't have a read one. The
write memory barrier makes sure that everything is written before the
barrier. It doesn't guarantee what order those writes become visible
in.
> Only then is the flag set atomically. If we want to be
> really sure, we could also add a Thread.MemoryBarrier() instruction before
> we open the lock like so:
> ...
> Thread.MemoryBarrier();
> Interlocked.Exchange(ref created, 1);
> ...
You'd need a memory barrier on read as well though - that's what would
make it thread-safe.
To me, this is looking a lot more complicated - and, as we've seen,
debatable in terms of thread-safety - than any of the more common
patterns.
-- Jon Skeet - <skeet@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too
- Next message: _: "Re: Writing to App.Config"
- Previous message: Peter Rilling: "Re: How can I enum the instance of forms?"
- In reply to: William Stacey: "Re: Simple and fast Singleton pattern for ya."
- Next in thread: William Stacey [MVP]: "Re: Simple and fast Singleton pattern for ya."
- Reply: William Stacey [MVP]: "Re: Simple and fast Singleton pattern for ya."
- Messages sorted by: [ date ] [ thread ]