21

With try-with-resource introduced in Java 7, I was surprised to see that that the Lock has not been retrofitted to be an AutoCloseable. It seemed fairly simple, so I have added it myself as follows:

class Lock implements AutoCloseable {
    private final java.util.concurrent.locks.Lock _lock;
    Lock(java.util.concurrent.locks.Lock lock) {
        _lock = lock;
        _lock.lock();
    }
    @Override 
    public void close() {
        _lock.unlock();
    }
}

This works with an AutoCloseableReentrantReadWiteLock class and usage is as follows:

try (AutoCloseableReentrantReadWiteLock.Lock l = _lock.writeLock()) {
    // do something
}        

Since this seems so straightforward and canonical use of auto-closing RAII I am thinking there must be a good reason this should not be done. Anybody know?

maaartinus
  • 44,714
  • 32
  • 161
  • 320
Miserable Variable
  • 28,432
  • 15
  • 72
  • 133

1 Answers1

23

This was a big debate when try-with-resources was proposed in February/March 2009.

Josh Bloch, the author of the proposal, said "This construct was designed for one thing and one thing only: resource management. It was not designed for locking."

There was a separate proposal to cover locks separately, but it didn't get anywhere.

I think the main reasons locks were not covered were:

  • not possible to add methods to an interface in Java 7
  • performance hit of creating an extra wrapper object that implemented the correct interface
  • philosophical objections to Lock being a different kind of resource from file handles (e.g. creation of a Lock does not entail invoking the lock method)

You can follow all the historical argy-bargy on the archive page, for example this thread.

rxg
  • 3,777
  • 22
  • 42
  • Thank you for the info; to me the lock seems like a resource but perhaps there are things I am missing. Working in Spring world, performance hit from wrappers is irrelevant. – Miserable Variable Jun 11 '13 at 16:54
  • @MiserableVariable: A lock is a resource, at least for me and Dijkstra (:D), see e.g. [the Banker's algorithm description](http://en.wikipedia.org/wiki/Banker's_algorithm#Resources). It's not necessary to create a new object each time (you only need something having a `close` method and can use it multiple times). – maaartinus Dec 13 '13 at 19:23
  • @maaartinus I am afraid I don't understand what you are saying. If you have a close method then you also need an open method, which is what the create does for the Lock class. – Miserable Variable Dec 13 '13 at 20:38
  • @Miserable Variable: You need an "open" method, but it can look like `AutoCloseable open() {lock(); return myCloseable;}` where `myCloseable` is a final field (and "closing" it obviously unlocks the lock). – maaartinus Dec 13 '13 at 21:49
  • @MiserableVariable: Sorry, I was confused... you're doing it right. – maaartinus Dec 14 '13 at 05:17
  • Is this answer still up to date for Java? – JFFIGK Nov 22 '19 at 11:32