什么是可重入锁ReentrantLock?

什么是可重入锁 ReentrantLock?

在并发编程中,线程安全是一个重要的概念,尤其是在多线程环境下,资源共享往往导致竞争条件。为了解决这个问题,Java 提供了多种同步机制,其中之一是可重入锁(ReentrantLock)。可重入锁允许同一个线程多次获取同一把锁,而不会导致死锁。

可重入锁的特点
  1. 重入性:同一个线程可以多次获取同一把锁,而不会被阻塞。例如,如果一个线程已经持有一个锁,再次尝试获取这个锁时,它可以直接获取成功,而不会被挂起。

  2. 独占性:在锁被一个线程持有的情况下,其他线程不能获取这个锁,必须等待直到锁被释放。

  3. 可公平性:ReentrantLock 可以选择公平性策略,确保线程获取锁的顺序是按照请求锁的顺序。如果设置为非公平锁,线程可以在没有任何顺序的情况下获取锁。

  4. 灵活性:ReentrantLock 提供了更高的灵活性和功能,比如可以中断锁的请求、增加时间限制等。

使用场景

可重入锁适用于需要递归调用的场景,例如在一个方法中调用另一方法,这两个方法都需要持有相同的锁来保护共享资源。使用 ReentrantLock 还可以通过其提供的方法来更好地控制并发行为。

Java 示例代码

以下是一个使用 ReentrantLock 的示例:

java 复制代码
import java.util.concurrent.locks.ReentrantLock;

class SharedResource {
    private final ReentrantLock lock = new ReentrantLock();
    private int counter = 0;

    // 增加计数器并打印当前值
    public void increment() {
        lock.lock(); // 获取锁
        try {
            counter++;
            System.out.println("Counter: " + counter);
            // 由于是可重入锁,这里可以再次尝试获取锁
            this.incrementInner();
        } finally {
            lock.unlock(); // 保证释放锁
        }
    }

    private void incrementInner() {
        lock.lock();
        try {
            counter++;
            System.out.println("Counter (inner): " + counter);
        } finally {
            lock.unlock();
        }
    }
}

public class ReentrantLockExample {
    public static void main(String[] args) {
        SharedResource sharedResource = new SharedResource();

        // 创建多个线程来测试可重入锁
        Thread thread1 = new Thread(sharedResource::increment);
        Thread thread2 = new Thread(sharedResource::increment);

        thread1.start();
        thread2.start();

        try {
            thread1.join();
            thread2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
代码解析
  1. 共享资源类 :定义了一个 SharedResource 类,其中包含一个 ReentrantLock 实例和一个整数计数器。
  2. increment 方法 :这个方法获取锁,增加计数器的值,然后调用另一个内部方法 incrementInner,这展示了 ReentrantLock 的重入特性,因为同一个线程可以再次获取已经持有的锁。
  3. incrementInner 方法:同样获取锁,增加计数器,并打印值。
  4. 主方法 :创建了两个线程,它们同时调用 increment 方法,从而测试了线程安全和可重入性。
最后小结下哈

ReentrantLock 是一种强大的工具,用于管理并发访问共享资源。通过允许可重入操作,它在保护数据一致性和提高系统性能方面发挥了重要作用。然而,使用可重入锁时,开发者需谨慎,确保在 try-finally 结构中释放锁,以避免潜在的死锁或资源泄漏问题。

相关推荐
2601_9615934212 小时前
Rust 开发环境配置繁琐?RustRover 开箱即用搞定编码调试
开发语言·后端·macos·rust
HZZD_HZZD13 小时前
DL/T 645-2026新国标深度解读与智能电表协议适配实战:从帧结构变化到Java采集器升级的全链路改造方案
java·开发语言
多加点辣也没关系15 小时前
JavaScript|第4章:类型转换
开发语言·javascript
聪慧的水蜜桃15 小时前
【YFIOs】用C#开发硬件之设备上云
开发语言·c#
yqcoder15 小时前
httpOnly 是什么,又有什么用?
开发语言·前端·javascript
山登绝顶我为峰 3(^v^)315 小时前
C/C++ 交叉编译方法
java·c语言·c++
一叶飘零_sweeeet16 小时前
Codex 与 Claude Code 深度拆解:两代 AI 编程智能体的技术本质与 Java 实战指南
java·ai·codex·claude code
Listen·Rain16 小时前
提示词和提示词模板
java·人工智能·spring boot
wuqingshun31415916 小时前
重写equals而不重写hashCode,会出什么问题?
java·开发语言