显示锁
Lock是显示锁的顶层实现的接口,所有的显示锁都是实现Lock接口
1、ReentrantLock
ReentrantLock是对Lock的实现,提供与synchronized相同的互斥性和内存可见性。
与进入或退出同步代码块相同的内存语义。
1.1 轮询锁与定时锁
内置锁中,死锁的唯一恢复途径是重启程序,防止死锁的唯一方法是避免锁顺序的不一致。
在不能获取所有需要的锁时,可采用定时锁和轮询锁,使你重新获取控制权,它会释放已经获得的锁,然后重新尝试获取所有锁或记录失败并采取其他措施。
1.2 可中断的锁获取操作
2、性能考虑因素
Java5中ReentrantLock明显高于内置锁,但是,性能这方面,只能说当时有效,有可能明天就不行了。还是要与时俱进。
3、公平性
当持有锁的时间较长或者请求锁的平均时间间隔长,使用<公平锁>。
在竞争激烈的情况下,非公平锁性能高于公平锁的性能的一个原因是:恢复一个被挂起的线程与该线程真正开始运行之间存在严重的延迟。
4、synchronized与ReentrantLock之间选择
仅当内置锁不能满足需求是,才可以考虑使用ReentrantLock,就是需要一些高级功能时:可定时的、可轮询的、可中断的锁获取操作,公平队列,非块结构的锁。否则,优先使用synchronized
5、读-写锁
ReentrantLock实现是标准的互斥锁,即同一时间最多只有一个线程能持有ReentrantLock,就会牺牲一些并发性。
而读-写锁的思想是:同时可以多读或者单写(两者不能同时发生)。只要保证每个线程都能确保读取到最新的数据,并且在读的时候不会有其他线程修改数据,就不会发生问题。
选择上,如果分析结果表明读-写锁没有提高性能,那么可以将读-写锁换成独占锁(ReentrantLock)。