Hi,
I like the C# implemention of singleton class presented at MSDN. My question
is that is it correct or right thing to do to modify that class to make the
class will return the same instance if for the same parameter when calling
GetInstance?
public static Singleton GetInstance(string parameter)
{
//using a hashtable or some other type to hold the instance - parameter
will be the key
//if the key exists and the instance is not null then return the
instance, otherwise create new instance and then add to hashtable
}
Thanks a lot!
John 11 1872
We're doing exactly this for many of our "singleton" classes, and it
works just fine. Whether it's thread-safe is another question entirely.
I'll leave that to Jon Skeet or someone else more familiar with
threading.
John,
In this case, it isn't really a singleton, in the sense that you have
more than one Singleton instance.
In order to guarantee thread safety, you should pass the hashtable to
the static Synchronized method on the Hashtable class. This will pass a
wrapper to you which will provide thread safety when performing operations
(read and write) on the Hashtable.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"John Lee" <jo***@newsgroup.nospam> wrote in message
news:Or**************@TK2MSFTNGP09.phx.gbl... Hi,
I like the C# implemention of singleton class presented at MSDN. My question is that is it correct or right thing to do to modify that class to make the class will return the same instance if for the same parameter when calling GetInstance?
public static Singleton GetInstance(string parameter) { //using a hashtable or some other type to hold the instance - parameter will be the key //if the key exists and the instance is not null then return the instance, otherwise create new instance and then add to hashtable }
Thanks a lot! John
John Lee <jo***@newsgroup.nospam> wrote: I like the C# implemention of singleton class presented at MSDN. My question is that is it correct or right thing to do to modify that class to make the class will return the same instance if for the same parameter when calling GetInstance?
public static Singleton GetInstance(string parameter) { //using a hashtable or some other type to hold the instance - parameter will be the key //if the key exists and the instance is not null then return the instance, otherwise create new instance and then add to hashtable }
As Nicholas said, that's not really a singleton - it's a factory
pattern implementation.
For thread safety, you should take out a lock:
static object mapLock = new object();
public static Singleton GetInstance (string parameter)
{
lock (mapLock)
{
// Check for existence, create new instance etc and return it
}
}
Don't try double-checked locking - unless you're *really, really*
confident that you're doing it right, and have got an expert to
validate it, preferrably by talking with even more experts, you may
well have a problem.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Thanks very much!!!
Is this a thread-safe implementation?
=============================================
private static Hashtable htAzApps;
public static AzManStore GetInstance(string applicationName)
{
lock (htAzApps.SyncRoot)
{
if (htAzApps == null)
{
htAzApps = new Hashtable();
instance = new AzManStore(applicationName);
}
else
{
if (htAzApps.ContainsKey(applicationName))
instance = (AzManStore)htAzApps[applicationName];
else
instance = new AzManStore(applicationName);
}
}
return instance;
}
=================================================
"Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message
news:MP************************@msnews.microsoft.c om... John Lee <jo***@newsgroup.nospam> wrote: I like the C# implemention of singleton class presented at MSDN. My question is that is it correct or right thing to do to modify that class to make the class will return the same instance if for the same parameter when calling GetInstance?
public static Singleton GetInstance(string parameter) { //using a hashtable or some other type to hold the instance - parameter will be the key //if the key exists and the instance is not null then return the instance, otherwise create new instance and then add to hashtable }
As Nicholas said, that's not really a singleton - it's a factory pattern implementation.
For thread safety, you should take out a lock:
static object mapLock = new object();
public static Singleton GetInstance (string parameter) { lock (mapLock) { // Check for existence, create new instance etc and return it } }
Don't try double-checked locking - unless you're *really, really* confident that you're doing it right, and have got an expert to validate it, preferrably by talking with even more experts, you may well have a problem.
-- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too
John, lock (htAzApps.SyncRoot) { if (htAzApps == null)
This will clearly not work. You have to verify that htAzApps != null
before the lock, or you'll get a NullReferenceException accessing
htAzApps.SyncRoot.
You can do what Jon showed you and lock on a separate object.
Mattias
--
Mattias Sjögren [MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
John Lee <jo***@newsgroup.nospam> wrote: Thanks very much!!!
Is this a thread-safe implementation?
============================================= private static Hashtable htAzApps;
public static AzManStore GetInstance(string applicationName) { lock (htAzApps.SyncRoot) { if (htAzApps == null) { htAzApps = new Hashtable(); instance = new AzManStore(applicationName); } else { if (htAzApps.ContainsKey(applicationName)) instance = (AzManStore)htAzApps[applicationName]; else instance = new AzManStore(applicationName); } } return instance; } =================================================
Not quite - look at what you're trying to lock on, and then think about
the first time through... I'd suggest having a static variable with an
object created just for locking.
(Note that you're also never saving the instance back into the hash
table, which I assume you want to be.)
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
I normally do not use the singleton pattern, in the GOF sense. But
instead a "canonical object", providing the same feature: a single place
in the code where you can obtain your singleton.
The canonical object has the benefit of not requiring static's, and thus
you can easily replace the canonical object with (for example) an other
implementation that does debug-logging.
Example implementation:
class AzManRegistry {
public static AzManRegistry Global = new Applications();
IDictionary existing;
public AzManRegistry() { existing = new Hashtable(); }
public AzManStore Instance(string applicationName) {
// Registry is monotonic, so we can use any existing
// entry if there is one... without synchronization
if ( existing.ContainsKey(applicationName) )
return existing[applicationName];
lock (existing.SyncRoot) {
// we need to recheck existance inside the critical region
if ( !existing.ContainsKey(applicationName) )
existing[applicationName] = new AzManStore(applicationName);
return (AzManStore)existing[applicationName];
}
}
}
some other place:
AzManRegistry.Global.Instance("foo");
--
Helge
Yes, you are right!
Does the following code work?
private static Hashtable htAzApps = new Hashtable();
public static AzManStore GetInstance(string applicationName)
{
lock (htAzApps.SyncRoot)
{
if (htAzApps.ContainsKey(applicationName))
instance = (AzManStore)htAzApps[applicationName];
else
{
instance = new AzManStore(applicationName);
htAzApps.Add(applicationName, instance);
}
}
return instance;
}
Thanks very much!
John
"Mattias Sjögren" <ma********************@mvps.org> wrote in message
news:ep****************@TK2MSFTNGP14.phx.gbl... John,
lock (htAzApps.SyncRoot) { if (htAzApps == null)
This will clearly not work. You have to verify that htAzApps != null before the lock, or you'll get a NullReferenceException accessing htAzApps.SyncRoot.
You can do what Jon showed you and lock on a separate object. Mattias
-- Mattias Sjögren [MVP] mattias @ mvps.org http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com Please reply only to the newsgroup.
Helge Jensen <he**********@slog.dk> wrote: I normally do not use the singleton pattern, in the GOF sense. But instead a "canonical object", providing the same feature: a single place in the code where you can obtain your singleton.
The canonical object has the benefit of not requiring static's, and thus you can easily replace the canonical object with (for example) an other implementation that does debug-logging.
Example implementation:
class AzManRegistry { public static AzManRegistry Global = new Applications(); IDictionary existing; public AzManRegistry() { existing = new Hashtable(); } public AzManStore Instance(string applicationName) { // Registry is monotonic, so we can use any existing // entry if there is one... without synchronization if ( existing.ContainsKey(applicationName) ) return existing[applicationName]; lock (existing.SyncRoot) { // we need to recheck existance inside the critical region if ( !existing.ContainsKey(applicationName) ) existing[applicationName] = new AzManStore(applicationName); return (AzManStore)existing[applicationName]; } } }
You're still relying on double-checked locking, which doesn't work in
..NET without extra volatility. In the above, I don't believe there's
anything to stop the JIT from reordering things such that the new entry
in the hashtable becomes visible before all the writes in the
AzManStore constructor have finished executing.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Jon Skeet [C# MVP] wrote: Helge Jensen <he**********@slog.dk> wrote:
You're still relying on double-checked locking, which doesn't work in .NET without extra volatility. In the above, I don't believe there's anything to stop the JIT from reordering things such that the new entry in the hashtable becomes visible before all the writes in the AzManStore constructor have finished executing.
BTW: the reason I posted the solution was to present the
"canonical-object" as opposed to the "singleton".
Secondly, I'm very interested in the actual problem in the code. The
code is almost identical to production-code I have written. So I am very
interested in knowing exactly what is wrong with it!
I'm not really _sure_ what's the problem. Is it the check outside the lock?
// Registry is monotonic, so we can use any existing // entry if there is one... without synchronization if ( existing.ContainsKey(applicationName) ) return existing[applicationName];
I can see the issue, if the impl. of "existing[object item] { set }",
changes the representation of "existing" in a way that makes a
concurrent "existing[object item] { get }" either: diverge, throw, or
(very inlikely) return true.
Is this the problem? I don't think it's a problem with
System.Collections.Hashtable though. (It's not a problem that would
occur in my own Hashtable implementation, due to care in the way the
underlying datastructure is updated :)
Or is it that the AzManStore constructor inside the lock can be moved
outside the lock and executed before the lock, effectively doing:
AzManStore _moved_outside_lock = new AzManStore(applicationName);
if ( existing.ContainsKey(applicationName) ) return existing[applicationName]; lock (existing.SyncRoot) { // we need to recheck existance inside the critical region if ( !existing.ContainsKey(applicationName) ) existing[applicationName] = _moved_outside_lock; return (AzManStore)existing[applicationName]; }
Which would seem pretty odd to me...
Best guess (from your explanation as I read it, I may be wrong) is that
the AzManStore-construtor would not have been completely evaluated
before invoking "existing[applicationName] { set }" on the new object.
But in that case locking wouldn't help at all, at least from what I can
reason.
or is it something even more exotic?
I would really appreciate an exact description, or reference to an
article, which would make it possible for me to understand and avoid
this problem .
--
Helge
Helge Jensen <he**********@slog.dk> wrote: You're still relying on double-checked locking, which doesn't work in .NET without extra volatility. In the above, I don't believe there's anything to stop the JIT from reordering things such that the new entry in the hashtable becomes visible before all the writes in the AzManStore constructor have finished executing. BTW: the reason I posted the solution was to present the "canonical-object" as opposed to the "singleton".
But if you're going to post sample code and suggest that people use it,
you should make sure it's thread-safe - certainly in a question about
thread safety!
Secondly, I'm very interested in the actual problem in the code. The code is almost identical to production-code I have written. So I am very interested in knowing exactly what is wrong with it!
I'm not really _sure_ what's the problem. Is it the check outside the lock?
Yes. Read up on double-checked locking and why it's broken in Java and
..NET. A simple google search should be fine. > // Registry is monotonic, so we can use any existing > // entry if there is one... without synchronization > if ( existing.ContainsKey(applicationName) ) > return existing[applicationName];
I can see the issue, if the impl. of "existing[object item] { set }", changes the representation of "existing" in a way that makes a concurrent "existing[object item] { get }" either: diverge, throw, or (very inlikely) return true.
Is this the problem? I don't think it's a problem with System.Collections.Hashtable though. (It's not a problem that would occur in my own Hashtable implementation, due to care in the way the underlying datastructure is updated :)
Or is it that the AzManStore constructor inside the lock can be moved outside the lock and executed before the lock, effectively doing:
To put it very briefly (as my dinner is waiting) - writes within the
constructor may be made visible to a reading thread *after* the write
into the hashtable. That means another thread could start using the
object before it had really been properly initialised.
--
Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet
If replying to the group, please do not mail me too This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: ajikoe |
last post by:
Hello,
Is anyone has experiance in running python code to run multi thread
parallel in multi processor. Is it possible ?
Can python manage which cpu shoud do every thread?
Sincerely Yours,...
|
by: Frank Jona |
last post by:
Intellisense with C# and a multi-file assembly is not
working. With VB.NET it is working.
Is there a fix availible?
We're using VisualStudio 2003
Regards
Frank
|
by: * ProteanThread * |
last post by:
but depends upon the clique:
...
|
by: frankenberry |
last post by:
I have multi-page tiff files. I need to extract individual frames from the
multi-page tiffs and save them as single-page tiffs. 95% of the time I
receive multi-page tiffs containing 1 or more black...
|
by: cody |
last post by:
What are multi file assemblies good for?
What are the advantages of using multiple assemblies (A.DLL+B.DLL) vs. a
single multi file assembly (A.DLL+A.NETMODULE)?
|
by: Joe |
last post by:
I have 2 multi-list boxes, 1 displays course categories based on a
table called CATEGORIES. This table has 2 fields CATEGORY_ID,
CATEGORY_NAME
The other multi-list box displays courses based on...
|
by: mimmo |
last post by:
Hi! I should convert the accented letters of a string in the correspondent
letters not accented. But when I compile with -Wall it give me:
warning: multi-character character constant
Do the...
|
by: Shane Story |
last post by:
I can seem to get the dimensions of a frame in a multiframe tiff.
After selecting activeframe, the Width/Height is still really much larger
than the page's actual dimensions.
When I split a...
|
by: Sabri.Pllana |
last post by:
We apologize if you receive multiple copies of this call for papers.
***********************************************************************
2008 International Workshop on Multi-Core Computing...
|
by: mknoll217 |
last post by:
I am recieving this error from my code:
The multi-part identifier "PAR.UniqueID" could not be bound.
The multi-part identifier "Salary.UniqueID" could not be bound.
The multi-part identifier...
|
by: CloudSolutions |
last post by:
Introduction:
For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
|
by: Faith0G |
last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
|
by: ryjfgjl |
last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
|
by: Charles Arthur |
last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
|
by: aa123db |
last post by:
Variable and constants
Use var or let for variables and const fror constants.
Var foo ='bar';
Let foo ='bar';const baz ='bar';
Functions
function $name$ ($parameters$) {
}
...
|
by: ryjfgjl |
last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
|
by: ryjfgjl |
last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
|
by: emmanuelkatto |
last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud.
Please let me know.
Thanks!
Emmanuel
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
| |