On Friday, September 2, 2016, Krystal Mok <rednaxel...@gmail.com> wrote:
> Hi Vitaly, > > Thanks for your comments! > > On Fri, Sep 2, 2016 at 7:55 PM, Vitaly Davidovich <vita...@gmail.com > <javascript:_e(%7B%7D,'cvml','vita...@gmail.com');>> wrote: > >> Hi Kris, >> >> >> On Friday, September 2, 2016, Krystal Mok <rednaxel...@gmail.com >> <javascript:_e(%7B%7D,'cvml','rednaxel...@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. > What about just the following (in Java 9): try (new Locker(lock)) { // } > > 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 :-) > Let's! :) As of right now, I consider EA as a bonus but never rely on it. Even simple cases like this, if inside a method that's considered too big for EA to run (particularly after inlining), will fail. > > And let's say when HotSpot gets a new JIT compiler, it'll have a more > effective EA. All the better. > You mean Graal? I'm with Remi - value types will make this much more palatable from an allocation perspective (and generally make more sense for uses like this than full blown reference types). > > Thanks, > Kris > > >> My $.02. >> >>> >>> Best regards, >>> Kris (OpenJDK username: kmo) >>> >> >> >> -- >> Sent from my phone >> > > -- Sent from my phone