Synchronized Hashtable

  • Thread starter Thread starter Urs Vogel
  • Start date Start date
U

Urs Vogel

Hi

I'm using static, synchronized Hashtables:

static Hashtable _htDiags = new Hashtable();
static Hashtable htDiags = Hashtable.Synchronized(_htDiags);

I'm not totally sure, if this protection wrapper is sufficient in a
mutlithreaded Singleton:
if((pi = (ProcessInfo)htDiags[PID]) != null)
pi.MyFunc();


Do I have to additionally lock access to htDiags object, or is
'synchronized' access sufficient? Like this:
lock(htDiags)
{
if((pi = (ProcessInfo)htDiags[PID]) != null)
pi.MyFunc();
}

Thanks for any hints.
Urs
 
Urs said:
I'm not totally sure, if this protection wrapper is sufficient in a
mutlithreaded Singleton:
if((pi = (ProcessInfo)htDiags[PID]) != null)
pi.MyFunc();

That would be fine, although you could skip using a Synchronized
singleton and use:

lock ( htDiags.SyncRoot ) {
pi = (ProcessInfo)htDiags[PID];
if ( pi != null )
pi.MyFunc();
}
Do I have to additionally lock access to htDiags object, or is
'synchronized' access sufficient? Like this:
lock(htDiags)
{
if((pi = (ProcessInfo)htDiags[PID]) != null)
pi.MyFunc();
}

The protocol is to lock htDiags.SyncRoot, not htDiags.

If you did a lookup and then mutation:

/***** ALERT, INVALID CODE HERE! ***/
pi = (ProcessInfo)htDiags[PID];
if ( pi == null ) {
pi = f();
htDiags[PID] = pi;
}
pi.MyFunc();

Here the synchronized wrapper of htDiags doesn't help you, and you need:

/* Proper code here */
lock ( htDiags.SyncRoot ) {
pi = (ProcessInfo)htDiags[PID];
if ( pi == null ) {
pi = f();
htDiags[PID] = pi;
}
pi.MyFunc();
}

Be really carefull about using Synchronized wrappers, they only
guarantee synchronization on each seperate method invocation. I prefer
writing the lock explicitly, even when only querying the collection --
if there is multithreading threats.
 
Back
Top