上一篇讲解了Lock接口核心API和相比于synchronized的关键优势,本文来进一步学习Lock接口的具体实现类ReentrantLock。
认识ReentrantLock
基本行为和语义
下面我们先看ReentrantLock的定义。
/**
* A reentrant mutual exclusion {@link Lock} with the same basic
* behavior and semantics as the implicit monitor lock accessed using
* {@code synchronized} methods and statements, but with extended
* capabilities.
*/
ReentrantLock是一种可重入的互斥锁Lock,其基本行为和语义与通过synchronized方法及语句访问的隐式监视器锁相同,但具备扩展功能。
那么synchronized有哪些基本行为和语义呢?通过前面文章的学习,我们已经知道synchronized具有上锁、解锁、互斥访问等行为,这些就是基本行为。synchronized修饰的方法或语句块所有操作作为一个不可分割的整体执行,也就是具有原子性;线程在释放锁之前会将共享变量的修改刷新到主内存,其他线程在获取锁后能立即看到最新值,也就是可见性;同一线程可以多次获取同一把锁,也就是可重入性。
/* <p>A {@code ReentrantLock} is <em>owned</em> by the thread last
* successfully locking, but not yet unlocking it. A thread invoking
* {@code lock} will return, successfully acquiring the lock, when
* the lock is not owned by another thread. The method will return
* immediately if the current thread already owns the lock. This can
* be checked using methods {@link #isHeldByCurrentThread}, and {@link
* #getHoldCount}.
*/
ReentrantLock的所有权归属于最后一个成功加锁但尚未解锁的线程。当锁未被其他线程持有时,调用lock()方法的线程将成功获取锁并返回。若当前线程已持有该锁,则此方法立即返回。可通过方法 isHeldByCurrentThread和 getHoldCount验证锁状态。
/* <p>The constructor for this class accepts an optional
* <em>fairness</em> parameter. When set {@code true}, under
* contention, locks favor granting access to the longest-waiting
* thread. Otherwise this lock does not guarantee any particular
* access order. Programs using fair locks accessed by many threads
* may display lower overall throughput (i.e., are slower; often much
* slower) than those using the default setting, but have smaller
* variances in times to obtain locks and guarantee lack of
* starvation. Note however, that fairness of locks does not guarantee
* fairness of thread scheduling. Thus, one of many threads using a
* fair lock may obtain it multiple times in succession while other
* active threads are not progressing and not currently holding the
* lock.
* Also note that the untimed {@link #tryLock()} method does not
* honor the fairness setting. It will succeed if the lock
* is available even if other threads are waiting.
*/
公平性设置
该类的构造函数接受一个可选的公平性参数,当设置为true时,在竞争条件下,锁优先授予等待时间最长的线程。否则,此锁不保证任何特定访问顺序。使用公平锁的多线程程序可能比默认设置(非公平锁)的整体吞吐量更低(即更慢,通常显著更慢), 但获取锁的时间波动更小,且能避免线程饥饿。需注意:锁的公平性并不保证线程调度的公平性。因此,当其他活跃线程未持有锁且未推进时,使用公平锁的某个线程可能连续多次获得锁。
另请注意:非超时的tryLock()方法不遵循公平性设置,只要锁可用,即使其他线程正在等待,它也会成功。
推荐用法
强烈建议在调用 lock()方法后立即使用 try 代码块,典型结构如下所示:
class X {
private final ReentrantLock lock = new ReentrantLock();
// ...
public void m() {
lock.lock(); // 阻塞直至获取锁
try {
// ... 方法逻辑
} finally {
lock.unlock(); // 确保释放锁
}
}
}
其他特性
/* <p>In addition to implementing the {@link Lock} interface, this
* class defines a number of {@code public} and {@code protected}
* methods for inspecting the state of the lock. Some of these
* methods are only useful for instrumentation and monitoring.
*
* <p>Serialization

最低0.47元/天 解锁文章
1364

被折叠的 条评论
为什么被折叠?



