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

相关推荐
郝亚军2 分钟前
IEEE 754 单精度浮点的SEM表示
开发语言·c++·算法
zhangjw349 分钟前
第15篇:Java多线程零基础入门,进程线程、线程创建方式、线程生命周期、线程安全彻底吃透
java·开发语言·面试
蝈理塘(/_\)大怨种10 分钟前
类和对象 (上)
java·开发语言
小新11031 分钟前
qt creator 将qInfo的输出日志写入日志文档,方便查看
开发语言·qt
我材不敲代码1 小时前
Python 函数核心:位置参数与关键字参数详解
java·前端·python
hssfscv1 小时前
QT的学习记录1
开发语言·qt·学习
SunnyDays10111 小时前
Python操作Excel批注:从基础添加到高级自定义的完整指南
开发语言·python·excel
Yyyyyy~2 小时前
【C++】数组篇
开发语言·c++
qq_333120972 小时前
C++高并发内存池的整体设计和实现思路_C 语言
java·c语言·c++
牛肉在哪里2 小时前
ros2 从零开始27 编写广播C++
开发语言·c++·机器人