Proposal: Automatic Resource Management
Matthias Ernst
matthias at mernst.org
Fri Mar 13 02:47:28 PDT 2009
On Sun, Mar 8, 2009 at 10:39 AM, Peter Mount <peter at retep.org.uk> wrote:
> On Sun, Mar 8, 2009 at 9:00 AM, Reinier Zwitserloot <reinier at zwitserloot.com
>> wrote:
>
>> We're veering waaay offtopic here; the ARM proposal does not address
>> locks. Period. Would everyone be happy if this was added in the 'major
>> disadvantages' section?
>
>
> Yes this is becoming more offtopic but hopefully my comments have brought up
> two points:
>
> 1: Although Locks are a form of resource, the ARM proposal as is cannot
> support them
> 2: Someone will abuse it to support Lock's at some point with potentially
> disastrous consequences.
What would be the problem with:
package j.u.c:
abstract class AbstractLock implements Lock {
private final AutoCloseable locked = new AutoCloseable() {
public void close() { AbstractLock.this.unlock(); }
}
public AutoCloseable locked() {
lock();
return locked;
}
}
Have the j.u.c locks inherit from AbstractLock.
Add in class LockSupport:
public static AutoCloseable locked(final Lock lock) {
return (lock instanceof AbstractLock) ?
((AbstractLock)lock).locked() : new AutoCloseable() {
public void close() { lock.unlock(); }
};
}
Use:
import static LockSupport.locked;
try(locked(guard)) {
}
Matthias
>
>
>>
>> If locks are truly deemed crucial, or the consensus is that,
>> eventhough evidently ARM-as-is can't do locks, people will try anyway
>> and the resulting confusion must be avoided, I suggest that the ARM
>> proposal is updated to do the right thing when an expression of type
>> Lock shows up in a try ( lockShowsUpHere ) { code} block. Someone else
>> proposed this before and I can't see any downside to this. It would be
>> bad if, for every release, a bunch more types get special uniquely
>> defined semantics in relation to the ARM expression, but that seems
>> very unlikely. Nobody else has named a use-case that doesn't work in
>> vanilla ARM yet seems likely to be abused, other than Lock, IIRC.
>
>
> Yes I did yesterday.
>
> The one thing I've learned from experience is that a lot of programmers are
> lazy when it comes to resources. Although for some resources are cleaned up
> occasionally by the garbage collector, most are not and unless the system is
> under heavy load the problem doesn't show itself until it's in the live
> environment. For this reason I do feel that the ARM proposal would alleviate
> this as long as the programmers know that the new construct exists.
>
> Now I do feel that Locks are a form of resource but one that is actively
> short lived. Although it seems simple to just write them manually with a try
> finally block you'll be surprised how easy it is for someone to miss the
> finally block or refactor it out without noticing. In a large system this
> can be costly (my gaming background coming in here).
>
> Over the last few years I've ended up wasting so much time debugging a
> complex system to locate a deadlock just to find that someone has forgotten
> to release a lock. It is this reason why I think the ARM proposal should
> support Lock's as a separate use-case.
>
> The main issues with Disposable and Lock that I can see are:
>
> 1: Lock is an interface and cannot extend Disposable as that would break
> existing code. Also implementing Disposable in the Lock implementations
> would not work if you use try( Lock ) as javac would not see it as being
> Disposable.
>
> 2: Normal resources are already open/active before the try so with
> Disposable the try(Disposable) would simply call Disposable.close() at the
> end. With Locks they are not active until lock() is called so try(Lock)
> would have to call Lock.lock() before the method body and then Lock.unlock()
> at the end.
>
> As I said in an earlier email I implement this pattern in JDK1.6 by having a
> set of annotations which with a processor inject the try...finally block
> around a method thats locked (yes I know annotation processors shouldn't do
> this but it's removed the problem completely). Having the ARM proposal would
> not just obsolete the hack but make it more flexible (as the hack only works
> at the method level).
>
> As for any other use-cases that don't work with the current proposal other
> than Lock, I can't think of any at the moment.
>
>
>>
>> --Reinier Zwitserloot
>>
>>
>> On Mar 8, 2009, at 09:03, Peter Mount wrote:
>>
>> > On Sun, Mar 8, 2009 at 7:58 AM, Jeremy Manson
>> > <jeremy.manson at gmail.com>wrote:
>> >
>> >> I am aware Lock is an interface. You wouldn't actually change the
>> >> Lock interface, you would change the classes. Just as they retrofit
>> >> Iterable everywhere. That's why I put "class Lock" there; perhaps it
>> >> would have been clearer if it said "class MyLock".
>> >
>> >
>> > What about when someone just references the lock as Lock rather than
>> > the
>> > implementing class? Javac won't be able to determine that the lock
>> > implements Disposable so in that case it will fail..
>> >
>> >
>> >
>> >
>> >>
>> >>
>> >> Jeremy
>> >>
>> >> On Sat, Mar 7, 2009 at 10:23 AM, Stephen Colebourne
>> >> <jodastephen at gmail.com> wrote:
>> >>> Jeremy Manson wrote:
>> >>>> The "right" fix, if we want to support this pattern, is to allow
>> >>>> the
>> >>>> try resource statement to accept expressions that return
>> >>>> Disposables,
>> >>>> and to retrofit the relevant lock APIs with disposables and lock
>> >>>> methods that return this:
>> >>>>
>> >>>> class Lock implements Disposable {
>> >>>> public Lock dlock() {
>> >>>> return this;
>> >>>> }
>> >>>> @Override public void dispose() {
>> >>>> unlock();
>> >>>> }
>> >>>> }
>> >>>>
>> >>> Lock is an interface. No changes are possible.
>> >>>
>> >>> Stephen
>> >>>
>> >>>
>> >>>
>> >>
>> >>
>> >
>> >
>> > --
>> > Peter Mount
>> > e: peter at retep.org.uk
>> > w: http://retep.org
>> > Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com
>> >
>>
>>
>>
>
>
> --
> Peter Mount
> e: peter at retep.org.uk
> w: http://retep.org
> Jabber/GTalk: peter at retep.org MSN: retep207 at hotmail.com
>
>
More information about the coin-dev
mailing list