July 30, 2006 Re: Proposals: Synchronization | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | Sean Kelly wrote: > Kent Boogaart wrote: >> 2. Don't permit arbitrary locking of objects. >> >> It is well accepted amongst the Java and .NET communities that allowing locking of arbitrary objects is a bad thing. For example, this is considered bad practice: >> >> public void myMethod() >> { >> ... >> lock (this) >> { >> ... >> } >> } >> >> It is bad because any other code could lock the object refered to by this. That can result in deadlocks, race conditions and all sorts of weird behavior. The accepted practice is: >> >> private object _lock = new object(); >> >> public void myMethod() >> { >> ... >> lock (_lock) >> { >> ... >> } >> } >> >> That way only the owning class can lock on the object. >> >> So my suggestion is to disallow locking on arbitrary objects and change the lock keyword to only allow locking on a Phobos-provided Lock class like this: >> >> private Lock _lock = new Lock(); //the Lock class or struct is implemented in Phobos >> >> public void myMethod() >> { >> lock (_lock) //OK >> { >> } >> >> lock (this) {} //compile error >> >> lock (new object()) {} //compile error >> } >> >> I would also suggest NOT allowing this syntax: >> >> public lock(_lock) void myMethod() >> { >> } >> >> Because it is ugly and synchronization is an implementation detail that should be kept out of the method signature. >> >> Pros: >> - the synch block can be removed from every object stored on the gc heap (that's a saving of at least 4 bytes per gc object - that's huge for applications that allocate a lot of small objects) >> - programmers are forced to lock in a safer manner. The problems of Java / .NET locking on arbitrary objects are avoided. >> - D will be able to provide better diagnostics of locks as a program runs and during debug sessions. Locks could be named, for example >> >> Cons: >> - none that I can think of > > This would make this currently legal syntax illegal: > > void fn() { > synchronized { > // stuff > } > } > > ie. where the synchronization object is implicit. I suppose its value is debatable, but I think it's sufficiently useful that I wouldn't want it to be illegal. > > > Sean Hum, I'm attracted to the idea that D's Objects would not have to have the monitor data. (altough I can't clearly say that the performance gain will be significative) I understand the "synchronized { ... }" statement might be useful, so perhaps we can have the best of both worlds? What if the implicit synchronized statement would call, similarly to operator overloading, a predefined lock function (or monitor member). Then we could have a mixin that would make a class lockable, by adding a monitor member, and perhaps a lock method. Such mixin should be defined by the standard lib, so that the user would not be required to write one. Then we would have code like this: class Foo { mixin Lockable; // std.thread.Lockable ? void fn() { synchronized { ... // stuff } } } which isn't that much more verbose, and now regular Objects would not have the monitor member. -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D |
Copyright © 1999-2021 by the D Language Foundation