Lock与ReentrantLock
Lock提供了一种无条件的, 可轮询的, 定时的以及可中断的锁获取操作, 所有加锁与解锁的方法都是显式的
ReentrantLock实现了Lock接口, 并提供了与synchronized相同的互斥性以及内存可见性
轮询锁与定时锁
轮询锁与定时锁模式是通过tryLock()方法实现的, 与无条件的锁获取模式相比, 它具有更完善的错误恢复机制
如下轮询锁示例:
- 通过tryLock可以避免顺序死锁, 若不能获取所有的锁时, 则会先释放所有的锁, 再重新尝试获取
- 休眠时间保护固定部分和随机部分, 可以降低活锁的可能性
如下定时锁示例:
- 实现了带有时间限制的操作, 若超时则返回平缓的失败
可中断的锁获取操作
- lockInterruptibly能够在获得锁的同时保持对中断的响应
- 定时的tryLock也能响应中断
性能考虑因素
- ReentrantLock可以构造公平锁, 当持有锁的时间相对较长, 或者请求锁的平均时间间隔较长, 那么应该使用公平锁
synchronized与ReentrantLock的选择
在一些内置锁无法满足需求的情况下, ReentrantLock可以作为一种高级工具, 当需要一些高级功能时才应该使用ReentrantLock, 这些功能包括: 可定时的, 可轮询的, 可中断的锁获取操作, 公平队列, 以及非块结构的锁, 否则, 还是应该优先使用synchronized
读写锁
- 允许多个读操作同时进行, 但每次只允许一个写操作
- 当访问以读取操作为主的数据结构时, 它能提高程序的可伸缩性
使用读写锁包装Map示例, 当需要例如对LinkedHashMap做包装时, 可以参考