在Java并发编程中,线程安全是一个核心问题。为了确保多个线程访问共享资源时不会发生数据不一致或竞态条件,Java提供了多种同步机制。其中,ReentrantLock 是一个强大且灵活的工具,它属于 java.util.concurrent.locks 包,是实现 可重入锁 的关键类。
ReentrantLock 是 Java 提供的一种显式锁(Explicit Lock),与 synchronized 关键字不同,它需要程序员手动获取和释放锁。它的“可重入”特性意味着:同一个线程可以多次获取同一把锁而不会造成死锁。
使用 ReentrantLock 需要遵循以下步骤:
ReentrantLock 对象lock() 方法获取锁finally 块中调用 unlock() 方法释放锁(非常重要!)下面是一个简单的示例:
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++; // 临界区代码 } finally { lock.unlock(); // 释放锁 } } public int getCount() { lock.lock(); try { return count; } finally { lock.unlock(); } }} 如果在 lock() 和 unlock() 之间发生异常,程序可能跳过 unlock(),导致锁永远无法释放,其他线程将永远等待——这就是死锁。因此,必须在 finally 块中释放锁,以确保即使发生异常也能正确释放。
| 特性 | ReentrantLock | synchronized ||------|----------------|---------------|| 锁获取方式 | 显式(需手动 lock/unlock) | 隐式(JVM 自动管理) || 可中断 | 支持(tryLock、lockInterruptibly) | 不支持 || 超时机制 | 支持(tryLock(timeout)) | 不支持 || 公平锁 | 支持(构造函数参数) | 不支持 || 条件变量 | 支持(newCondition()) | 仅 wait/notify | ReentrantLock 提供了比 synchronized 更丰富的功能,但也更易出错(如忘记 unlock)。因此,在简单场景下,synchronized 仍是首选;在需要高级功能(如超时、公平锁)时,才考虑使用 ReentrantLock。
ReentrantLock 默认是非公平锁(性能更好),但你可以通过构造函数启用公平锁:
// 公平锁ReentrantLock fairLock = new ReentrantLock(true);// 非公平锁(默认)ReentrantLock unfairLock = new ReentrantLock(); 公平锁保证等待时间最长的线程优先获取锁,避免线程饥饿,但吞吐量较低。非公平锁允许插队,效率更高,但可能导致某些线程长时间等待。
ReentrantLock 是 Java并发编程 中实现 线程安全 的重要工具。它提供了比 synchronized 更灵活的控制能力,包括可中断锁、超时锁、公平锁和多条件变量等。然而,使用时务必注意在 finally 块中释放锁,避免死锁。
掌握 ReentrantLock 和 可重入锁 的原理,将帮助你编写更高效、更可靠的并发程序。对于初学者来说,建议先从 synchronized 入手,再逐步过渡到 ReentrantLock 的高级用法。
本文由主机测评网于2025-12-13发表在主机测评网_免费VPS_免费云服务器_免费独立服务器,如有疑问,请联系我们。
本文链接:https://www.vpshk.cn/2025127117.html