并发编程原理与实战(十八)ReentrantLock API全面解析

上一篇讲解了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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

帧栈

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值