On Wed, 30 May 2012 16:46:54 +0100, Andrei Alexandrescu
<seewebsiteforem...@erdani.org> wrote:
On 5/30/12 2:34 AM, deadalnix wrote:
Le 29/05/2012 23:33, Andrei Alexandrescu a écrit :
On 5/29/12 1:37 AM, deadalnix wrote:
I would say that breaking things here, with the right deprecation
process, is the way to go.
So what should we use for mutex-based synchronization if we deprecate
synchronized classes?
Andrei
I think something similar to range design here is the way to go.
It is easy to define something like
template isLockable(T) {
enum isLockable = isShared!T && is(typeof(T.init.lock())) &&
is(typeof(T.init.release()));
}
And allow locking only if(isLockable!Type) .
Now we can create SyncObject or any structure we want. The point is that
we lock explicit stuff.
But in this design anyone can lock such an object, which was something
you advocated against.
I think there is some confusion here as to what the "problem" is and is
not.
The problem is /not/ that you can lock any object.
The problem is /not/ that we have synchronized(object) {}
The problem is /not/ that we have synchronized classes/methods.
The problem /is/ that synchronized classes/methods use a mutex which is
exposed publicly, and it the same mutex as used by synchronized(object)
{}. This exposure/re-use makes deadlocks more likely to happen, and
harder to spot.
Removal of this "problem" will not stop deadlocks from happening as
they're a problem multi-threaded/lock based code will always have (*). It
will however make them far less likely to happen accidentally. It will
make programmers think about what/where/when and how to lock things rather
than blithely using synchronized everywhere. It will mean using locks is
not as easy as currently, though I think we can make it fairly nice with
good library code and/or some co-operation between the runtime and
synchronized() statements i.e. requiring the class implement a common
Lockable interface for example.
The fact that every object can be locked, and this means they all use more
memory is a side issue - arguably as important for some.
R
(*) the best you can do to "solve" the deadlock problem is to impose lock
acquisition ordering on your code, as in all locks must be acquired in a
defined order, and if not an assertion/error/exception is thrown. This
requires some sort of static/singelton/overlord class which is aware of
all mutexes and is involved in all acquisitions/releases.
--
Using Opera's revolutionary email client: http://www.opera.com/mail/