ReentrantLock通过维护线程持有标识和重入计数实现可重入性,同一线程可多次获取锁,计数器递增,释放时递减至零才真正释放;示例中increment调用nestedIncrement体现重入特性,配合try-finally确保释放锁;支持公平与非公平模式,默认非公平性能更高;提供lock、unlock、tryLock等方法,增强并发控制灵活性,需注意成对调用及异常安全。

在Java中,ReentrantLock 是一种可重入的互斥锁,它提供了比 synchronized 更灵活的锁定机制。所谓“可重入”,指的是同一个线程可以多次获取同一把锁而不会造成死锁。下面详细解析 ReentrantLock 如何实现可重入特性,并展示其基本使用方式。
可重入锁允许当前持有锁的线程再次进入被该锁保护的代码块。比如一个线程已经获得了某个锁,当它再次请求这个锁时,可以直接获得,而不是被阻塞。JVM 中的 synchronized 关键字是可重入的,而 ReentrantLock 也实现了同样的语义。
ReentrantLock 的可重入性是通过内部维护一个持有锁的线程标识和一个计数器来实现的:当线程第一次获取锁时,计数器设为1;每次重入时计数器加1;释放锁时计数器减1,直到为0才真正释放锁。
以下是一个典型的 ReentrantLock 使用场景:
立即学习“Java免费学习笔记(深入)”;
import java.util.concurrent.locks.ReentrantLock;
public class Counter {
private int count = 0;
private final ReentrantLock lock = new ReentrantLock();
public void increment() {
lock.lock(); // 获取锁
try {
count++;
System.out.println(Thread.currentThread().getName() + " count: " + count);
if (count < 5) {
nestedIncrement(); // 调用另一个需要同一把锁的方法
}
} finally {
lock.unlock(); // 释放锁
}
}
public void nestedIncrement() {
lock.lock(); // 同一线程可重复进入
try {
count++;
System.out.println(Thread.currentThread().getName() + " (nested) count: " + count);
} finally {
lock.unlock();
}
}
}
在这个例子中,increment() 方法调用了 nestedIncrement(),两个方法都使用了同一个 ReentrantLock 实例加锁。由于 ReentrantLock 支持可重入,同一线程不会因为重复加锁而阻塞自己。
ReentrantLock 构造时可以选择是否启用公平策略:
公平锁会记录等待队列,确保等待最久的线程优先获取锁;而非公平锁允许插队,可能导致新来的线程先于等待中的线程获取锁。
ReentrantLock 提供了一些比 synchronized 更丰富的控制能力:
例如,使用 tryLock 避免无限等待:
if (lock.tryLock(3, TimeUnit.SECONDS)) {
try {
// 执行操作
} finally {
lock.unlock();
}
} else {
System.out.println("未能获取锁");
}
使用 ReentrantLock 时必须注意以下几点:
基本上就这些。ReentrantLock 在需要更细粒度控制并发时非常有用,理解其可重入机制有助于写出更安全的多线程代码。
以上就是Java里如何使用ReentrantLock实现可重入锁_ReentrantLock可重入锁操作解析的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号