一、Lock与 ReentrantLock
Lock 提供一种无条件的、可轮询的、定时的、可中断的锁获取操作,全部加锁和解锁的方法都是显式的。
public interface Lock { void lock(); // 获取锁。 void lockInterruptibly() throws InterruptedException; // 假设当前线程未被中断,则获取锁。 boolean tryLock(); // 仅在调用时锁为空暇状态才获取该锁。 // 假设锁在给定的等待时间内空暇,而且当前线程未被中断,则获取锁。 boolean tryLock( long time, TimeUnit unit) throws InterruptedException; void unlock(); // 释放锁。 Condition newCondition(); // 返回绑定到此 Lock 实例的新 Condition 实例。 }
Lock lock = new ReentrantLock(); lock.lock(); try { // 更新对象状态 // 捕获异常,并在必要时恢复不变性条件 } finally{ lock.unlock(); }
1 轮询锁与定时锁 通过tryLock来避免锁顺序死锁
2 可中断的锁获取操作
public boolean sendOnSharedLine(String message) throws InterruptedException { lock.lockInterruptibly(); try { return cancellableSendOnSharedLine(message); } finally { lock.unlock(); } } private boolean cancellableSendOnSharedLine(String message) throws InterruptedException { }
3 非块结构的加锁
二、性能考虑因素
ReentrantLock在Java 5.0比内置锁提供更好的竞争性能。 Java 6使用了改进后的算法来管理内置锁,与在ReentrantLock中使用的算法类似,该算法有效地提高了可伸缩性。
三、公平性
ReentrantLock的构造函数提供两种公平性选择:非公平锁、公平锁。 针对Map的性能測试,公平锁、非公平锁、ConcurrentHashMap。
四、在synchronized和ReentrantLock之间进行选择
在一些内置锁无法满足需求的情况下,ReentrantLock能够作为一种高级工具。当须要一些高级功能时才应该使用ReentrantLock,这些功能包含:可定时的,可轮询的与可中断的锁获取操作,公平队列,及非块结构的锁。否则,还是应该优先使用synchronized.
五、读-写锁