using this as synchronization object
Hello everyone,
As mentioned in this article, why using this or type itself as lock object is bad idea? What means "it potentially offers public scope to the synchronization object"?
http://www.albahari.com/threading/part2.html
I quote the whole paragraph below,
--------------------
Choosing the Synchronization Object
Any object visible to each of the partaking threads can be used as a synchronizing object, subject to one hard rule: it must be a reference type. It’s also highly recommended that the synchronizing object be privately scoped to the class (i.e. a private instance field) to prevent an unintentional interaction from external code locking the same object. Subject to these rules, the synchronizing object can double as the object it's protecting, such as with the list field below:
Code:
class ThreadSafe {
List <string> list = new List <string>();
void Test() {
lock (list) {
list.Add ("Item 1");
...
A dedicated field is commonly used (such as locker, in the example prior), because it allows precise control over the scope and granularity of the lock. Using the object or type itself as a synchronization object, i.e.:
Code:
lock (this) { ... }
or:
lock (typeof (Widget)) { ... } // For protecting access to statics
is discouraged because it potentially offers public scope to the synchronization object.
--------------------
thanks in advance,
George
Re: using this as synchronization object
Quote:
Originally Posted by George2
Hello everyone,
As mentioned in this article, why using this or type itself as lock object is bad idea? What means "it potentially offers public scope to the synchronization object"?
Hi George,
In my opinion, the concepts of synchronization is a low level part of the implementation thus should be well hidden from the user.
The synchronization implemented as locking the "this" or "typeof(Widget)" could be potencially dangerous since other code (e.g. more high level code that uses your library) could lock the object which has already been locked.
Re: using this as synchronization object
Thanks Igor,
I am confused about your comments, "could lock the object which has already been locked"? Lock is exclusive and if the lock is acquired by some other party, how can the current party acquire the lock again? If I do not quite catch your points, please feel free to correct me. :-)
Quote:
Originally Posted by Igor Soukhov
Hi George,
In my opinion, the concepts of synchronization is a low level part of the implementation thus should be well hidden from the user.
The synchronization implemented as locking the "this" or "typeof(Widget)" could be potencially dangerous since other code (e.g. more high level code that uses your library) could lock the object which has already been locked.
regards,
George
Re: using this as synchronization object
Quote:
Originally Posted by George2
Lock is exclusive and if the lock is acquired by some other party, how can the current party acquire the lock again?
A lock is exclusive to a thread. Once a thread has the lock, no other thread can take that lock. However, a thread can take the same lock multiple times, it just increments a counter.
It means code like this works fine:
Code:
public void Method1()
{
lock (myLockObject)
Method2();
}
public void Method2()
{
lock (myLockObject)
DoStuff();
}
There you have the lock twice.
Re: using this as synchronization object
Thanks Mutant_Fruit,
As mentioned, using this as lock object compared with using private member as lock object is more prone to have deadlock. Could you help to describe a scenario why using this object is more prone please?
Quote:
Originally Posted by Mutant_Fruit
A lock is exclusive to a
thread. Once a thread has the lock, no other thread can take that lock. However, a thread can take the same lock multiple times, it just increments a counter.
It means code like this works fine:
Code:
public void Method1()
{
lock (myLockObject)
Method2();
}
public void Method2()
{
lock (myLockObject)
DoStuff();
}
There you have the lock twice.
regards,
George
Re: using this as synchronization object
Quote:
Originally Posted by George2
Thanks Igor,
I am confused about your comments, "could lock the object which has already been locked"? Lock is exclusive and if the lock is acquired by some other party, how can the current party acquire the lock again? If I do not quite catch your points, please feel free to correct me. :-)
I should've written it as "attempt to lock the object that has already been locked".
But - you see, you've made important point here - if you keep that "sync object" public so that anyone could lock or unlock it - that raises more questions than if had you kept it private.
Re: using this as synchronization object
Thanks Igor,
I agree with you. Question answered.
Quote:
Originally Posted by Igor Soukhov
I should've written it as "attempt to lock the object that has already been locked".
But - you see, you've made important point here - if you keep that "sync object" public so that anyone could lock or unlock it - that raises more questions than if had you kept it private.
regards,
George