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/

Reply via email to