Hello. I hope all is well.
Do you believe it is a bad idea to enrich the Lock interface with a set of default methods that safely release the lock once ready? Consider the following (dangerous) example. final Lock lock = new ReentrantLock (); lock.lock(); /* Code that may throw an exception */ lock.unlock(); This example will never release the lock if an exception is thrown, as the programmer didn’t wrap this up in a try/finally. Adding a default method within the Lock interface, called withLock(Runnable) for example or any better name, would streamline this, as shown next. default void withLock(final Runnable runnable) { requireNonNull(runnable, "Cannot run a null"); lock(); try { runnable.run(); } finally { unlock(); } } The caller can now simply change the above example into the following, without having to worry about this. final Lock lock = new ReentrantLock (); lock.withLock(() -> { /* Code that may throw an exception */ }); We can have more variants of these default methods, as shown next. default <T> T getWithLock(final Supplier<T> supplier) { requireNonNull(supplier, "The supplier cannot be null"); lock(); try { return supplier.get(); } finally { unlock(); } } Any thoughts? With kind regards, Albert Attard