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

Reply via email to