在阅读ReentrantLock
的源代码时,我发现它内部使用了一个扩展AbstractQueuedSynchronizer
的同步器来控制锁。Doug Lea在本文中提到CCD_;模板方法模式";,这有助于简化子类的编码。
然而,Joshua Bloch在Effective Java中建议;偏爱组合而非继承";,因为";与方法调用不同,继承违反了封装;。在我的理解中;模板";在春季(例如RedisTemplate
、TransactionTemplate
等(遵循此规则。
因此,回到AbstractQueuedSynchronizer
和ReentrantLock
中定义的同步器,我想知道它的设计(基于模板方法模式(是否有任何缺点。非常感谢!
在AbstractQueuedSynchronizer
的情况下没有缺点,因为AbstractQueuedSynchronizer
是以这样一种方式精心编写的,即继承不会违反封装:
- 子类没有可见字段
- 所有方法(5个受保护的方法除外(都是
final
,因此子类不能更改它们 - 子类只允许重写5个受保护的方法:
tryAcquire()
、tryRelease()
、tryAcquireShared()
、tryReleaseShared()
和isHeldExclusively()
实际上,这个实现相当于组合:只需将5个可重写的方法移动到一个专用接口。