Java ReentrantLock的可重入性与公平锁机制详解

 更新时间:2026年02月14日 15:34:34   作者:晔子yy  
这篇文章主要介绍了Java ReentrantLock的可重入性与公平锁机制,Java中的ReentrantLock是一个可重入的互斥锁,基于AQS实现,它允许同一线程多次获取同一把锁,并控制加锁与释放,支持公平/非公平策略及tryLock等灵活特性,需要的朋友可以参考下

1.ReentrantLock介绍

ReentrantLock​ 是Java 并发包(java.util.concurrent.locks)中提供的一个可重入互斥锁,功能类似于synchronized关键字,但提供了更灵活的锁控制机制。

2.ReentrantLock核心特性

2.1可重入性

同一个线程可以多次获取同一把锁,而不会产生死锁

ReentrantLock lock = new ReentrantLock();
public void func1() {
    lock.lock();
    try {
        inner();
    } finally {
        lock.unlock();
    }
}
public void func2() {
    lock.lock();  // 同一个线程可以再次获取锁
    try {
        // 操作
    } finally {
        lock.unlock();
    }
}

2.2公平性选择

支持公平锁和非公平锁两种模式

默认使用非公平锁,非公平锁和公平锁的区别在于公平锁多了判断在等待队列中是否已经有线程在排队的条件。

  • 非公平锁:默认,吞吐量高
  • 公平锁:按等待时间分配,避免饥饿
// 非公平锁
ReentrantLock unfairLock = new ReentrantLock();
// 公平锁
ReentrantLock fairLock = new ReentrantLock(true);

2.3中断响应

支持在等待锁的过程中响应中断

使用lock.lockInterruptibly()即可设置可中断的获取锁

public void method() throws InterruptedException {
    lock.lockInterruptibly();  // 可中断的获取锁
    try {
        // 操作
    } finally {
        lock.unlock();
    }
}

2.4超时机制

  • tryLock():立即返回是否获取成功
  • tryLock(long timeout, TimeUnit unit):带超时的尝试

3.ReentrantLock基本使用方法

我们来模拟一个简单的多线程环境下对单一共享变量做更改的场景

public class Counter {
    private final ReentrantLock lock = new ReentrantLock();
    private int count = 0;
    public void increment() {
        lock.lock();  // 获取锁
        try {
            count++;
        } finally {
            lock.unlock();  // 必须放在finally中确保释放
        }
    }
}

和sychronized类似,其本质都是将需保证线程安全的变量放到代码块中,使用锁将代码块包裹。不一样的点在于Reentrantlock需要手动释放锁,为了保证每次使用锁后安全地释放,我们使用finally关键字去实现锁的释放。

4.ReentrantLock和sychronized对比

synchronized和ReentrantLock都是Java 中提供的可重入锁,但却有着较多的不同点

ReentrantLock与synchronized对比

ReentrantLocksynchronized
实现方式Java代码实现JVM内置(C/C++)
锁获取方式手动 lock()/unlock()自动获取/释放
可中断性lockInterruptibly()不支持
超时机制tryLock()不支持
公平锁支持不支持
性能优化AQS+CAS锁升级

虽说在性能上二者相差无几,但是ReentrantLock提供了更多可选的功能,灵活性要比传统synchronized锁要更高,所以在大部分场景中,我们会选择使用ReentrantLock作为第一选择,而synchronized因为其有着自动获取和释放锁的优势,在简单的业务场景中会经常看见它的身影。

5.ReentrantLock使用主要事项

5.1锁的释放

由于ReentrantLock没有提供自动获取和释放锁,所以在每次使用完后必须手动释放

lock.lock();
try {
    // 临界区代码
} finally {
    lock.unlock();
}

5.2锁的层级嵌套

虽然ReentrantLock支持可重入锁,但是随着嵌套层级增加,代码可读性会大大下降

//嵌套层次过深
public void methodA() {
    lock.lock();
    try {
        methodB();
    } finally {
        lock.unlock();
    }
}
public void methodB() {
    lock.lock();  // 再次获取
    try {
        // ...
    } finally {
        lock.unlock();
    }
}

以上就是Java ReentrantLock的可重入性与公平锁机制详解的详细内容,更多关于Java ReentrantLock的资料请关注脚本之家其它相关文章!

相关文章

  • java如何实现嵌套对象转大map(扁平化)

    java如何实现嵌套对象转大map(扁平化)

    这篇文章主要介绍了java如何实现嵌套对象转大map(扁平化),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • SpringBoot@Aspect 打印访问请求和返回数据方式

    SpringBoot@Aspect 打印访问请求和返回数据方式

    这篇文章主要介绍了SpringBoot@Aspect 打印访问请求和返回数据方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • 详解Java并发编程基础之volatile

    详解Java并发编程基础之volatile

    volatile作为Java多线程中轻量级的同步措施,保证了多线程环境中“共享变量”的可见性。这里的可见性简单而言可以理解为当一个线程修改了一个共享变量的时候,另外的线程能够读到这个修改的值。本文将详解介绍Java并发编程基础之volatile
    2021-06-06
  • SpringBoot实现阿里云快递物流查询的示例代码

    SpringBoot实现阿里云快递物流查询的示例代码

    本文将基于springboot实现快递物流查询,物流信息的获取通过阿里云第三方实现,具有一定的参考价值,感兴趣的可以了解一下
    2021-10-10
  • java 获取当前路径下的所有xml文档的方法

    java 获取当前路径下的所有xml文档的方法

    这篇文章主要介绍了java如何获取当前路径下的所有xml文档,需要的朋友可以参考下
    2014-05-05
  • Java中StringBuilder类的用法解析

    Java中StringBuilder类的用法解析

    StringBuilder是一个可变的字符序列,这个类提供了一个与StringBuffer兼容的API。本文主要为大家介绍了StringBuilder类的常用用法,需要的可以参考一下
    2023-05-05
  • RabbitMQ实现延时消息的两种方法实战教程

    RabbitMQ实现延时消息的两种方法实战教程

    这篇文章主要介绍了RabbitMQ实现延时消息的两种方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-09-09
  • Java正则表达式学习之分组与替换

    Java正则表达式学习之分组与替换

    这篇文章主要给大家介绍了关于Java正则表达式学习之分组与替换的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • mybatis-generator自动生成dao、mapping、bean配置操作

    mybatis-generator自动生成dao、mapping、bean配置操作

    这篇文章主要介绍了mybatis-generator自动生成dao、mapping、bean配置操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • java 实现最小二叉树堆排序的实例

    java 实现最小二叉树堆排序的实例

    这篇文章主要介绍了java 实现最小二叉树堆排序的实例的相关资料,希望通过本文能帮助到大家,需要的朋友可以参考下
    2017-09-09

最新评论