While reading the source code of ReentrantLock, I found that internally it use a synchronizer which extends AbstractQueuedSynchronizer to control the lock. Doug Lea mentioned in this paper that AbstractQueuedSynchronizer serves as a "template method pattern", which helps simplify the coding of sub-classes.
However, Joshua Bloch advised in Effective Java that we should "favor composition over inheritance", because "unlike method invocation, inheritance violates encapsulation". And in my understanding, the "templates" in Spring (e.g. RedisTemplate, TransactionTemplate, etc.) follow this rule.
So, back to the AbstractQueuedSynchronizer and the synchronizer defined in ReentrantLock, I would like to know if its design (based on template method pattern) has any disadvantages. Many thanks!
In case of
AbstractQueuedSynchronizerthere are no disadvantages, becauseAbstractQueuedSynchronizeris carefully written in such a way that inheritance doesn't violate encapsulation:final, so child classes cannot change themtryAcquire(),tryRelease(),tryAcquireShared(),tryReleaseShared()andisHeldExclusively()Effectively this implementation is equivalent to composition: just move the 5 overridable methods to a dedicated interface.