By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,874 Members | 1,027 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,874 IT Pros & Developers. It's quick & easy.

Thread safety in Hashtables remove method ..

P: n/a
Hello!

I'm am currently working on making a central cache component threadsafe, and
was looking at the synchronized implementation of the Hashtable. I was
wondering why you'd really want to enforce thread safety in a remove method?

Why would you care if two threads are trying to remove the same key from the
hashtable? In the end, the key is removed (and that was probably what you
were looking for).

Maybe this is caused by me not reading the following code correctly - and
not seing what it actually does is to make sure that no two threads are
removing keys, while other operations are performed on the hashtable (by
other threads).

public override void Remove(object key)
{
object local;

Monitor.Enter(local = _table.get_SyncRoot());
try
{
_table.Remove(key);
}
finally
{
Monitor.Exit(local);
}
}

--
venlig hilsen / with regards
anders borum
--
Nov 16 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
> Why would you care if two threads are trying to remove the same key from the
hashtable? In the end, the key is removed (and that was probably what you
were looking for).
The problem is that the Hashtable can be grown by adding items while items are
being removed. These growth operations change the way the Hashtable works
such that if the Remove method init's it's search values for finding the key,
and then
the underlying collection changes, you'll get erroneous results.

If the method were to take a local reference of buckets, then even stranger
results
would occur. When the collection was grown, the key would be removed from the
previous collection, and not the grown collection. In effect the item wouldn't
be
removed.
--
Justin Rogers
DigiTec Web Consultants, LLC.
Blog: http://weblogs.asp.net/justin_rogers
Maybe this is caused by me not reading the following code correctly - and
not seing what it actually does is to make sure that no two threads are
removing keys, while other operations are performed on the hashtable (by
other threads).

public override void Remove(object key)
{
object local;

Monitor.Enter(local = _table.get_SyncRoot());
try
{
_table.Remove(key);
}
finally
{
Monitor.Exit(local);
}
}

--
venlig hilsen / with regards
anders borum
--

Nov 16 '05 #2

P: n/a
Hello!

So the locking process occurs on the entire instance of the instance,
effectively serializing all write (or change operations), so that only on
thread is able to change the instance at any given time?

Naturally all threads are allowed read operations.

Considering the following two methods, I would like to know if the locking
occurs on the instance (_table.get_SyncRoot()) or on the local object
variable (named "local").

public override void Add(object key, object value)
{
object local;
Monitor.Enter(local = _table.get_SyncRoot());
try
{
_table.Add(key, value);
}
finally
{
Monitor.Exit(local);
}
}

public override void Remove(object key)
{
object local;
Monitor.Enter(local = _table.get_SyncRoot());
try
{
_table.Remove(key);
}
finally
{
Monitor.Exit(local);
}
}

... isn't the above equal to (given that the entire instance is locked):

public override void Remove(object key)
{
object local;
lock(local = _table.get_SyncRoot());
{
_table.Remove(key);
}
}

or simply this:

public override void Remove(object key)
{
lock(_table.get_SyncRoot());
{
_table.Remove(key);
}
}

Thanks in advance. I am really currently reading up on threading and would
like some pointers to emphasize what I get from the books. The more I read,
the more I understand just how important thread safety is to e.g.
collections that serve as caches ..

--
venlig hilsen / with regards
anders borum
--
Nov 16 '05 #3

P: n/a
Anders Borum <a@b.dk> wrote:
So the locking process occurs on the entire instance of the instance,
effectively serializing all write (or change operations), so that only on
thread is able to change the instance at any given time?
Yes.
Naturally all threads are allowed read operations.
That's not necessarily "natural" - if a writing thread temporarily has
the table in an invalid state, reading from it would be a bad idea.
Considering the following two methods, I would like to know if the locking
occurs on the instance (_table.get_SyncRoot()) or on the local object
variable (named "local").
They're the same thing. The code below is exactly equivalent to

lock (_table.SyncRoot)
{
...
}

as you suggested (using the property syntax rather than calling the
get_SyncRoot method directly).
Thanks in advance. I am really currently reading up on threading and would
like some pointers to emphasize what I get from the books. The more I read,
the more I understand just how important thread safety is to e.g.
collections that serve as caches ..


See http://www.pobox.com/~skeet/csharp/threads/ for most of what I know
about threading.

--
Jon Skeet - <sk***@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Nov 16 '05 #4

P: n/a
Hello!
That's not necessarily "natural" - if a writing thread temporarily has
the table in an invalid state, reading from it would be a bad idea.
Sorry; What I ment was, that from what I have seen in the Hashtable, reading
operations are not synchronized. Again, this is because the implementation
of the Hashtable allows for this. I agree with you that one could easily
think of situations where all operations on a instance are synchronized.
as you suggested (using the property syntax rather than calling the
get_SyncRoot method directly).
The code was taken directly from Salamanders C# decompiler. I am using the
SyncRoot property in my own code. Also thanks for clearing up the
lock(this); code.
See http://www.pobox.com/~skeet/csharp/threads/ for most of what I know
about threading.


I'll read that right away.

--
venlig hilsen / with regards
anders borum
--
Nov 16 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.