Please: try-with-resouces Lock support!

Reinier Zwitserloot reinier at zwitserloot.com
Fri Mar 4 05:47:12 PST 2011


To summarize the log, you can't tell the difference between generics on the
type of a variable declaration and the lesser than operator:

try (x < y ? resourceA : resourceB) {}

vs:

try (x<y> z = resourceA) {}


An LL(k) parser can't tell the difference until its too late. A packrat/rd
parser could, but both javac and ecj are LL(k) parsers so changing this
would require both to be rewritten from scratch.

Re-introducing the ability to use just an expression here would require some
sort of keyword or symbol that is unambiguous. This could work:

try (= expression) {}

but it breaks the principle of least surprise, in that without knowing a
heck of a lot about the capabilities of LL(k) parsers, the need for the =
sign is a mystery.

I gather from this discussion as well as the reaction to the fine work by
Heinz Kabutz that the primary use case for expressions in ARM statements is
locks, and this use case is not good enough, even if it is actually fast
enough at least on server mode VMs.

 --Reinier Zwitserloot



On Sat, Feb 26, 2011 at 4:19 AM, Howard Lovatt <howard.lovatt at gmail.com>wrote:

> I haven't checked the specification, but on the latest JDK from the
> Mercurial repository:
>
>  try ( l.autoLock() ) { ... }
>
> Is fine,
>
>  -- Howard.
>
> On 26 February 2011 13:18, David Holmes <David.Holmes at oracle.com> wrote:
> > Howard,
> >
> > The t-w-r needs a resource declaration, so as per my example you'd still
> > need to do:
> >
> > try ( Lock l2 = l.autolock()) { ... }
> >
> > Using defenders to retrofit AutoCloseable to Lock does make it simpler to
> > implement.
> >
> > However there's still additional overhead here and I wouldn't vote for
> this.
> >
> > David
> >
> > Howard Lovatt said the following on 02/26/11 10:40:
> >>
> >> The use case:
> >>
> >> try ( new ReentrantLock() ) { ... }
> >>
> >> makes no sense, you *need* to share the lock. However if Lock were
> >> modified to use defender methods:
> >>
> >> interface Lock extends AutoCloseable {
> >>
> >>  ... // As before
> >>
> >>  Lock autoLock()  default Trait.autoLock;
> >>
> >>  // Similarly autoLockInterruptibly
> >>
> >>  void close() default Trait.close;
> >>
> >>  static final class Trait {
> >>    public Lock autoLock(final Lock self) {
> >>      self.lock();
> >>      return self;
> >>    }
> >>
> >>    // Similarly autoLockInterruptibly
> >>
> >>    public void close(final Lock self) {
> >>      self.unlock();
> >>    }
> >>  }
> >> }
> >>
> >> Then
> >>
> >> try (l.autoLock()) { ... }
> >>
> >> would work.
> >>
> >>  -- Howard.
> >>
> >> On 24 February 2011 11:42, David Holmes <David.Holmes at oracle.com>
> wrote:
> >>>
> >>> I suspect Joe will shut this down as being out of scope for coin-dev in
> >>> its present state, but my 2c
> >>>
> >>> Gernot Neppert said the following on 02/24/11 03:31:
> >>>>
> >>>> this has been discussed here before, but somehow got lost:
> >>>> Wouldn't it be very handy having a class
> >>>> "java.util.concurrent.AutoLockable" that could be used as follows:
> >>>
> >>> No not really. The way try-with-resources has evolved really doesn't
> >>> mesh with lock usage. As Neal already mentioned the overhead of
> creating
> >>> the AutoLockable per lock operation is simply prohibitive. Even if you
> >>> retrofitted Lock with AutoCloseable you would still need (given t-w-r
> >>> synatx) to have a helper method to acquire the lock and return it so
> you
> >>> can assign it to the local:
> >>>
> >>>  try ( Lock l = Lock.lockAndReturn(lock) ) {
> >>>  ...
> >>>  }
> >>>
> >>> This is just a round-hole vs square-peg situation, and trying to make
> it
> >>> fit really doesn't add anything to clarity or useability in my view.
> >>>
> >>> I can imagine a more general (more specific?) t-w-r that might allow:
> >>>
> >>> try (lock) {
> >>>   ...
> >>> }
> >>>
> >>> but that would be for future debate.
> >>>
> >>> Cheers,
> >>> David Holmes
> >>>
> >>>> try(AutoLockable locked = AutoLockable.locked(lock))
> >>>> {
> >>>> // Do something in locked scope
> >>>> }
> >>>>
> >>>> It would look something like this:
> >>>>
> >>>> package java.util.concurrent.locks;
> >>>>
> >>>> public abstract class AutoLockable implements AutoCloseable {
> >>>>
> >>>>     public static AutoLockable locked(final Lock lock)
> >>>>     {
> >>>>         lock.lock();
> >>>>         return new AutoLockable() {
> >>>>
> >>>>             @Override
> >>>>             public void close() {
> >>>>                 lock.unlock();
> >>>>             }
> >>>>         };
> >>>>     }
> >>>>
> >>>>     public abstract void close();
> >>>> }
> >>>>
> >>>>
> >>>
> >>
> >>
> >>
> >
>
>
>
> --
>   -- Howard.
>
>



More information about the coin-dev mailing list