什么是可重入锁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 结构中释放锁,以避免潜在的死锁或资源泄漏问题。

相关推荐
csbysj20201 小时前
XSLFO 区域
开发语言
江南十四行1 小时前
Java并发编程中的锁机制:synchronized与Lock详解
java·开发语言
SamDeepThinking1 小时前
所有的框架源码,最怕的就是被debug
java·后端·程序员
道剑剑非道1 小时前
FFmpeg + Qt 实现摄像头采集与 MP3 背景音乐 RTSP 推流
开发语言·qt·ffmpeg
吴声子夜歌1 小时前
Java——字符编码
java·字符编码·char
冷小鱼1 小时前
多线程编程深度解析:Java与Python框架实战指南
java·开发语言·python·多线程
武帝为此1 小时前
【C语言进程与线程】
c语言·开发语言
fox_lht1 小时前
第十一章 错误处理
开发语言·后端·rust
叼烟扛炮1 小时前
C++ 知识点12 构造函数
开发语言·c++·算法·构造函数