A bit of sugar for j.u.c.locks with try-with-resources?

Krystal Mok rednaxelafx at gmail.com
Sat Sep 3 03:28:03 UTC 2016


Hi Vitaly,

Thanks for your comments!

On Fri, Sep 2, 2016 at 7:55 PM, Vitaly Davidovich <vitalyd at gmail.com> wrote:

> Hi Kris,
>
>
> On Friday, September 2, 2016, Krystal Mok <rednaxelafx at gmail.com> wrote:
>
>> Hi core-libs developers,
>>
>> I mostly live down in the VM world, but recently I've been playing with
>> j.u.c.locks a bit, and saw that there's an opportunity to retrofit the API
>> with the try-with-resources syntax. I wonder if anybody has brought this
>> topic up before; apologies if there had been.
>>
>> From the JavaDoc of j.u.c.l.ReentrantLock, the following is a typical
>> usage:
>>
>>  class X {
>>    private final ReentrantLock lock = new ReentrantLock();
>>    // ...
>>
>>    public void m() {
>>      lock.lock();  // block until condition holds
>>      try {
>>        // ... method body
>>      } finally {
>>        lock.unlock()
>>      }
>>    }
>>  }
>>
>> The try...finally construction really pops out as a try-with-resources
>> candidate.
>>
>> So what if we retrofit that with something like:
>>
>>  class X {
>>    private final ReentrantLock lock = new ReentrantLock();
>>    // ...
>>
>>    public void m() {
>>      try (lock.lock()) { // block until condition holds
>>        // ... method body
>>      }                   // automatic unlock at the end
>>    }
>>  }
>
> This is Java 9 syntax right? Java 7-8 require an assignment to a local in
> the TWR block.
>

Yes, this is Java 9 syntax, although I was actually intending to use the
old Java 7/8 syntax as the example...got too used to the new goodies.


>
>> Assuming lock.lock() returns a temporary wrapper object (let's call it a
>> "Locker" for this discussion), where Locker implements AutoCloseable, and
>> its close() method calls lock.unlock().
>> That'll make the API look and feel quite similar to the built-in
>> "synchronized () { ... }" syntax. With escape analysis and scalar
>> replacement implemented correctly in the VM, this temporary Locker object
>> wouldn't incur much (or any) runtime cost after optimized JIT'ing, so it
>> feels like a pure win to me.
>>
>> What do you think?
>
> So using TWR with scoped objects, such as this, is used quite a bit; I've
> seen this idiom many times, and have used it myself.
>
> Now, what's the value add to have this in the JDK? One can write such a
> Locker themselves quite easily.
>
> Having the Locker integrated into the API makes the experience smoother.
If we write our own wrapper, it might look like:

try (locker = new Locker(lock)) {
  // ... method body
}

Which is okay-ish. Or maybe with the help of some statically imported
helper method and the Java 9 syntax:

try (locker(lock)) {
  // ...
}

Hmm...I can live with that.

I also don't hold as much confidence in EA as you, apparently - it's too
> brittle and unpredictable in its current form, IMHO.  Of course when the
> allocation doesn't matter, that part isn't a big deal.
>
> Haha, I know how C2's EA isn't giving everybody the kind of confidence
they want. But for simple cases like this it should work nicely (and if
not, let's fix it :-)

And let's say when HotSpot gets a new JIT compiler, it'll have a more
effective EA. All the better.

Thanks,
Kris


> My $.02.
>
>>
>> Best regards,
>> Kris (OpenJDK username: kmo)
>>
>
>
> --
> Sent from my phone
>


More information about the core-libs-dev mailing list