synchronized (this[.classinfo]) in druntime and phobos
Regan Heath
regan at netmail.co.nz
Tue May 29 05:07:29 PDT 2012
On Tue, 29 May 2012 01:08:59 +0100, Jonathan M Davis <jmdavisProg at gmx.com>
wrote:
> On Tuesday, May 29, 2012 01:54:59 Alex Rønne Petersen wrote:
>> On 29-05-2012 01:41, Jonathan M Davis wrote:
>> > On Tuesday, May 29, 2012 01:35:23 Alex Rønne Petersen wrote:
>> >> I don't think arguing about them makes sense at this point. Way too
>> much
>> >> code would break if we changed the semantics. I'd consider it a
>> mistake
>> >> and a lesson learned, rather.
>> >>
>> >> But I take it you agree that synchronized (this) and similar
>> >> "uncontrollable" synchronization blocks should be avoided?
>> >
>> > I'm not an expert on threading stuf, but it would be my opinion that
>> if
>> > you're not intending to protect the entire class with locks that it
>> makes
>> > no sense to lock on the class itself. You're locking for something
>> > specific, in which case, your sychronized block should be locking on
>> > something else specific to what you're trying to protect. Certainly,
>> > that's how I'd approach it with mutexes. You don't have a mutex for an
>> > entire class unless it's actually used for all of the class'
>> functions.
>> > Rather, you use mutexes specific to what you're trying to protect.
>> >
>> > - Jonathan M Davis
>>
>> Right, but even if you really *are* protecting the entire class, you can
>> still create mysterious deadlocks if users of your code lock on your
>> class. So I'm arguing that no matter the use case, never lock on a
>> 'this' reference exposed outside of some API layer.
>
> Well, it seems pretty abysmal to me to be locking on something that you
> don't control. Making a mutex that your class used public would just be
> stupid.
Interestingly this is what C#s Array type does with SyncRoot
(intentionally).
> With synchronized classes/functions, you're basically creating and using
> an
> implicit mutex for the whole class, which would then be the same as if
> you locked it at the beginning of every member function call and
> unlocked it at its end, which doesn't expose the mutex at all. So, I
> don't really see te
> problem there would have to study the matter more to see what the issue
> there is.
According to the docs here:
http://dlang.org/class.html#synchronized-functions
A synchronized function locks "this" and as "this" is exposed publicly...
In the following code the "lock" statement and "synchronized void bar"
lock the same mutex.
class Foo {
synchronized void bar() { ...statements... }
}
void main()
{
Foo foo = new Foo();
lock(foo)
{
...statements...
}
}
> But locking on another class rather than something specifically intended
> as a mutex does seem to me like it's asking for trouble.
Yep. It commonly arises where you have a class/object which is either not
synchronized itself (because it might be used in single threaded
situations and you want performance) like a collection class for example,
or is synchronized but you need to lock a sequence of member function
calls i.e. a lookup and insert on the collection. What happens then, is
people just call lock(<object>) and end up locking the same mutex as the
class does internally. What happens next to cause a deadlock is that
inside that lock they call one or more functions or methods which
internally call methods on another synchronized object. This results in a
locking pattern of object1, object2. In another piece of code, running in
another thread, they do something similar which results in a locking
pattern of object2, object1 and eventually these threads will deadlock
each other.
R
--
Using Opera's revolutionary email client: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list