Threads fundamental question

J

John

The code:
---------
class sample{
static readonly object mylock=new object():

Hashtable Mytable=new Hashtable();

public void Add(object a)
{
Mytable.Add(a.Key,a);
}
public void Remove(object a)
{
Mytable.Remove(a.Key);
}

}
The Question:
-------------
What is the difference between :
1.
public void Add(object a)
{
lock(mylock)
{
Mytable.Add(a.Key,a);
}
}
2.
public void Add(object a)
{
lock(this)
{
Mytable.Add(a.Key,a);
}
}
3.
public void Add(object a)
{
lock(Mytable)
{
Mytable.Add(a.Key,a);
}
}
4.
public void Add(object a)
{
lock(Mytable.Syncroot)
{
Mytable.Add(a.Key,a);
}
}
5.
public void Add(object a)
{
lock(Syncroot)
{
Mytable.Add(a.Key,a);
}
}
 
G

Guest

In all your cases the difference is what is getting locked. The lock keyword
maps to a Monitor object that is hung off of every object in .NET (at least
conceptionally). This object is not actually created until you use the lock
statement on the object (for performance reasons). By using lock you are
preventing anybody else from access the object. Of course as with normal
locks this only works if everybody else also locks the object before using
it. Therefore your various cases are simply determining which object to
lock. The effect is the same but the consequences are not. The larger the
object you lock (in terms of exposed surface, not actual size) the more
likely you are to cause a request to stall. For example if you use
lock(this) in all your property and method calls then you basically force all
access to your class members to be serialized. This can be a good thing but
in general this is not what you want. However if you use lock(Mytable) only
in those properties or methods that actually need the hashtable then calls to
your class are not serialized unless they call one of the impacted methods.

The general rule of thumb is to lock the smallest object that you can. In
your case I'd lean toward the hashtable. I have never found lock(this) to be
useful although .NET does provide a special attribute for just that purpose.
For collections they have the SyncRoot property to expose an object that can
be locked instead of the collection itself and this should normally be used.

Having said all that I should point out that most times you want any number
of callers to be able to read an object but only one writer. In this case
you should use ReaderWriterLock instead. This is the best performer in this
case. However this is overkill for values that rarely change. In the case
of rarely changing values I'd go with a private dummy object in the class
that you use the lock statement on when needed. As recommended by MS you
should really never use this, a public object or a type in the lock
statement. I also avoid value types (if that even works).

In a nutshell for values that rarely change or for cases where
reading/writing is not that important then use this code:

class MyClass
{
private object m_lckObj = new object();

public void Foo ( )
{
lock(m_lckObj)
{
...
};
}
}

For cases where the value is read a lot and written frequently and
performance is critical then:

class MyClass
{
private ReaderWriterLock m_lckObj = new ReaderWriterLock();

public void FooRead ( )
{
m_lckObj.AcquireReadLock(timeout);
try
{
...
} finally
{
m_lckObj.ReleaseReaderLock();
};
}

public void FooWrite ( )
{
m_lckObj.AcquireWriterLock(timeout);
try
{
...
} finally
{
m_lckObj.ReleaseWriterLock();
};
}
}

Hope this helps,
Michael Taylor - 9/16/05
 
J

John

Hi Michael

I thank you for your answer which i found enlighting.

I read it many times these are my new questions on your answer :

*I'm not clear about the difference of locking the Hashtable or the
dummy object.
To me it is exactly the same?

*I have been told that the hastable is thread safe. What is the meaning
of that since i still have to lock.

*Also if i lock the Hastable access, do i have to lock the objects that
will make use of it if they can be accessed by more than one thread ?

*What did you mean by "As recommended by MS you
should really never use this, a public object or a type in the lock
statement. I also avoid value types (if that even works)."

I don't understand "..a public object or a type in the lock
statement. I also avoid value types (if that even works)."

Thanks
John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads

synchronization demo 7
about using the Lock synchorization mechanism 5
Is this Threadsafe? 10
Question on Locking and Deadlocks 7
lock 7
synchronizations of threads 1
Use of event handling 6
deadlock 2

Top