返回

ReentrantLock 简介及与 synchronized 比较

Android

ReentrantLock 简介

ReentrantLock 是 Java 并发编程库中的一种锁机制,它允许一个线程多次获取同一把锁。与 synchronized 不同,ReentrantLock 可以更精细地控制锁的获取和释放,并提供了一些额外的特性,例如中断锁等待、尝试获取锁以及公平锁等。

ReentrantLock 的用法

要使用 ReentrantLock,您需要先创建一个 ReentrantLock 对象,然后使用 lock() 方法获取锁,并在使用完毕后使用 unlock() 方法释放锁。例如:

ReentrantLock lock = new ReentrantLock();

lock.lock();
try {
    // 执行临界区代码
} finally {
    lock.unlock();
}

ReentrantLock 与 synchronized 的比较

ReentrantLock 与 synchronized 都是 Java 中的锁机制,但它们之间存在一些关键的区别:

  • 重量级与轻量级: ReentrantLock 是一个重量级锁,而 synchronized 是一个轻量级锁。重量级锁是指获取和释放锁都需要花费较长时间,而轻量级锁则相反。
  • 可中断性: ReentrantLock 支持中断锁等待,而 synchronized 不支持。这意味着如果一个线程正在等待获取锁,而另一个线程需要中断它,可以使用 ReentrantLock 的 interrupt() 方法来中断等待。
  • 尝试获取锁: ReentrantLock 提供了尝试获取锁的方法,即 tryLock() 方法。如果锁已经被其他线程获取,tryLock() 方法将立即返回 false,而不会阻塞线程。
  • 公平锁: ReentrantLock 可以设置为公平锁,这意味着获取锁的顺序与线程请求锁的顺序是一致的。synchronized 则不是公平锁,获取锁的顺序与线程请求锁的顺序无关。

何时使用 ReentrantLock

ReentrantLock 适用于需要精细控制锁的获取和释放、需要中断锁等待、需要尝试获取锁或需要使用公平锁的情况。例如,在以下场景中可以使用 ReentrantLock:

  • 多个线程同时访问共享资源,需要防止数据竞争。
  • 需要控制线程获取锁的顺序,确保公平性。
  • 需要中断一个正在等待锁的线程。
  • 需要尝试获取锁,而不阻塞线程。

何时使用 synchronized

synchronized 适用于需要简单、轻量级的锁机制的情况。例如,在以下场景中可以使用 synchronized:

  • 单个线程访问共享资源,不需要考虑数据竞争。
  • 不需要控制线程获取锁的顺序。
  • 不需要中断一个正在等待锁的线程。
  • 不需要尝试获取锁,而是直接阻塞线程。

结论

ReentrantLock 和 synchronized 都是 Java 中常用的锁机制,但它们各有优缺点和适用场景。在选择使用哪种锁机制时,需要根据具体情况进行权衡。