类说明
ReetrantLock
是一个可重入排它Lock
,和使用synchronized
方法和语句的隐式监视器锁有着相同的基本行为和语义,但是有着扩展性能。
ReentrantLock
由上次成功加锁但是还没有解锁的线程所持有。在锁没有被其他线程持有时,一个线程调用lock
将返回成功获取锁。如果当前线程已经持有锁那么该方法将立即返回。这个可以使用方法isHeldByCurrentThread
和getHoldCount
检查。
这个类的构造器接收一个可选的公平性参数。当设为 true 时,在争用的情况下,锁倾向于授权给等待时间最长的线程。另外,这个锁不保证任何特定访问顺序。使用被多个线程访问的公平锁的程序将呈现比使用默认设置的情况较低的总吞吐量(也就是变慢了,通常是慢很多),但是在获取锁和保证不饥饿的时间上有较小的方差。
公平锁可以保证锁的获取按照FIFO原则,而代价是进行大量的线程切换。非公平性锁虽然可能造成线程饥饿,但是较少线程切换,保证了很大的吞吐量。
同样需要注意的是,不计时的tryLock()
方法不赞成公平设置。如果锁是可用的它将成功获得锁,而不管其他线程是否正在等待。
建议实践时永远在lock
后面立即跟上一个try
块,大多数典型的在构造之前/之后的情况是:
class X{
private final ReentrantLock lock = new ReentrantLock();
//...
public void m(){
lock.lock(); // block until condition holds
try{
// ... method body
} finally {
lock.unlock();
}
}
}
除了实现Lock
接口,这个类定义了大量 public 和 protected 方法来检查锁的状态。其中有一些方法只用于仪表和监控。
这个类的序列化和内置锁的行为方式一致:反序列化的锁是处于解锁状态,在序列化的时候不管当前它的状态。
这个锁支持相同线程递归锁最大2147483647次。尝试超过这个限制将导致从加锁方法抛出Error
。
参考资料
JDK 1.7