Java并发编程:ReentrantLock深度解析与实战

0 下载量 146 浏览量 更新于2024-08-03 收藏 454KB PDF 举报
"Java 多线程与并发(11-26)-JUC锁- ReentrantLock详解" Java 并发编程中的ReentrantLock(可重入锁)是Java.util.concurrent包下的一个高级锁机制,它提供了比内置的synchronized关键字更细粒度的控制。ReentrantLock在JDK 5.0被引入,作为对Java并发编程库(Java Concurrency Utilities,简称JUC)的重要补充。ReentrantLock的实现基于AbstractQueuedSynchronizer(AQS),一个用于构建锁和其他同步组件的框架。 1. 可重入锁的原理与作用: 可重入锁允许一个线程多次获取同一锁,而不阻塞其他线程。这在递归调用或同一个线程需要在多个同步块中使用同一锁的情况下非常有用。如果一个线程试图获取已经被它持有的锁,那么锁会识别出这一情况并允许再次获取,而不会造成死锁。 2. ReentrantLock与AQS的关系: ReentrantLock的核心是AQS,它是通过内部类Sync实现的。Sync是一个抽象静态内部类,它进一步分为两个子类:FairSync(公平锁)和NonfairSync(非公平锁)。这两个子类分别实现了公平和非公平的锁获取策略。 3. 公平锁与非公平锁: - 公平锁:按照线程等待的顺序来分配锁,确保每个线程都有机会获得锁,但可能会导致整体吞吐量降低,因为线程需要等待队列中的所有其他线程释放锁。 - 非公平锁:不保证等待的线程会按顺序获取锁,有可能线程会在队列前部直接获取锁,这样可以提高总体性能,但也可能导致饥饿问题,即某些线程可能长时间无法获取锁。 4. 默认实现: ReentrantLock的默认实现是非公平锁。可以通过构造函数传入boolean参数来指定是否使用公平锁。 5. 示例分析: 使用ReentrantLock创建公平锁和非公平锁,可以通过如下代码实现: ```java // 创建公平锁 ReentrantLock fairLock = new ReentrantLock(true); // 创建非公平锁 ReentrantLock unfairLock = new ReentrantLock(); ``` 6. ReentrantLock与synchronized的对比: - 功能性:ReentrantLock提供了更多功能,如tryLock()尝试获取锁,lockInterruptibly()可响应中断,以及Condition接口用于精确的线程唤醒。 - 性能:在无竞争情况下,synchronized可能比ReentrantLock更快,因为它由JVM直接支持。但在竞争激烈的情况下,ReentrantLock通常表现更好。 - 锁释放:synchronized在异常情况下会自动释放锁,而ReentrantLock需要显式调用unlock()方法。 了解这些基本概念后,深入阅读ReentrantLock的源码,可以更清晰地理解其内部的工作机制,包括锁获取、释放、线程等待队列的管理等。这对于理解和优化多线程程序,以及准备BAT等大厂的面试都是非常有帮助的。