Proposal: Automatic Resource Management (original) (raw)

Joshua Bloch jjb at google.com
Fri Mar 13 11:27:58 PDT 2009


Hi Neal,

Please take a look my recent response to Mark Mahieu. Briefly, I want to prepare a survey of types for which automatic resource management would be useful. I believe this is best done collaboratively, as all of us have expertise in different areas. I have started the document, and I welcome all contributions. I believe that this document will go a long way towards answering these questions.

      Josh

On Fri, Mar 13, 2009 at 9:54 AM, Neal Gafter <neal at gafter.com> wrote:

I agree that one might want to avoid this construct in performance critical code, and I also agree that it probably doesn't make sense to add a construct that addresses locks in particular (but only locks). I think Jeremy was right when he suggested that locks are being discussed as a proxy for a category of resources that are not well handled by the proposal in its current form.

On Fri, Mar 13, 2009 at 9:26 AM, Joshua Bloch <jjb at google.com> wrote: > Matthias, > > Hi. This would work, but I'd have concerns about the performance. Locks have > to be really fast. If we want to solve the locking case (and I'm not so > sure we do), I believe that we should do so with another construct. I made > a "Preproposal" for such a construct, but no one showed any enthusiasm. > > Josh > > On Fri, Mar 13, 2009 at 2:47 AM, Matthias Ernst <matthias at mernst.org> wrote: > >> 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