All locks in Java are reentrant. They have to be in so that the owner of a monitor can reenter protected code. If a thread requests a lock that it already holds, it’ll be given it. Without this, a subclass couldn’t override a snynchronised method and then call the superclass method without deadlocking.
Java’s ReentrantReadWriteLock is about acquiring separate read and write locks for efficiency. For example, in the case where you may have infrequent writes but frequent reads, it may be more efficient to not synchronise all access with just one lock. Instead, ReentrantReadWriteLock can allow all read access to only block when a write is taking place. You’ll end up with multiple simultaneous reads but synchronised writes and all the reads will have guaranteed visibility of the writes.
With all Lock implementations, you specifically acquire the lock and are politely asked to release the lock within a finally block. Makes sense but gives unlock responsibility on the developer.
Vanilla Java would have you;
Lockl=...;l.lock();try{// access the resource protected by this lock}finally{l.unlock();}
Why not wrap the boiler plate code up in a mini DSL and pass in a lambda to execute the cleanup? Any implementation must call both lock and unlock and re-throw any exceptions. The following test shows this to be true.
Having the micro-DSL pass in the generic Callable on the static constructor meant that I couldn’t make just the method generic and instead had to link the types by making the class definition generic. You might also notice that the Callable used isn’t Java’s Callable, as Sun saw fit not to have the Exception as a generic type.
By creating a new Callable interface with a generic exception, I was able to neaten up the DSL so that we’re not forced to throw Exception from a method that uses the ExecuteUsingLock class. Instead, you define your closure function to throw RuntimeException.
A real world example might be something that updates a status probe where the variable lock below is an instance of ReentrantReadWriteLock.