ReentrantLock原理及详细的使用方法

ReentrantLock详解(可重入、可中断、锁超时、公平锁、条件变量)、同步模式之顺序控制 文章目录1.ReentrantLock详解1.1 可重入1.2 可中断 lockInterruptibly()1.3 设置超时时间 tryLock()1.4 通过lock.tryLock()来解决, 哲学家就餐问题1.5 公平锁 new ReentrantLock(true)1.6 条件变量 Condition 1.ReentrantLock详解 相对于synchronized 它具备如下特点 可中断 可以设置超时时间 可以设置为公平锁 支持多个条件变量 与 synchronized 一样,都支持可重入 阅读详情
AI摘要

本文围绕Java并发编程中的可重入锁展开,介绍其基本原理,包括基于AQS实现、可重入性及公平与非公平锁;阐述详细使用方法,如基本使用、尝试获取锁等;分析内部实现机制;还给出使用注意事项,如手动释放锁、避免死锁等,提供更灵活的锁控制。

ReentrantLock 是 Java 并发编程中一种重要的同步机制,它比传统的 synchronized 提供了更高的灵活性和功能。下面将从 ReentrantLock 的基本原理、详细使用方法、内部实现机制、注意事项等方面详细说明。

一、ReentrantLock 的基本原理

ReentrantLock 是基于可重入的概念设计的锁。当一个线程已经获取了 ReentrantLock 锁,它可以再次进入该锁的同步代码块而不会陷入死锁。这是因为 ReentrantLock 记录了每个线程获取锁的次数,并允许同一线程多次获取它。线程获取锁的次数与释放锁的次数必须匹配,才能真正释放锁。

1.1 AQS(AbstractQueuedSynchronizer)

ReentrantLock 的核心是基于 AQS(抽象队列同步器)实现的。AQS 维护了一个队列,用于管理所有请求锁的线程。每个线程尝试获取锁时,如果当前锁被其他线程持有,则进入等待队列,阻塞等待锁释放。一旦锁释放,AQS 会从队列中唤醒下一个线程,允许它获取锁。

1.2 可重入性

可重入锁允许线程多次进入同一把锁。比如,一个递归方法可以在方法调用链中多次获取同一个锁而不导致死锁。这种特性主要依赖于线程独有的锁计数器。

1.3 公平锁与非公平锁
  • 公平锁:按照线程请求锁的顺序进行排队,先到先得。公平锁避免了线程“饥饿”,但性能可能比非公平锁稍低。
  • 非公平锁:线程直接尝试获取锁,不关心等待队列中的其他线程,可能会导致某些线程长期等待。非公平锁性能较高,因为它减少了上下文切换和线程调度的开销。

二、ReentrantLock 的详细使用方法

ReentrantLock 提供了比 synchronized 更多的控制能力,如尝试获取锁、可中断锁等待、锁的公平性等。下面逐一介绍其主要用法。

2.1 基本使用

在使用 ReentrantLock 时,通常遵循以下步骤:

  1. 创建锁对象:通过 new ReentrantLock() 创建锁实例。
  2. 获取锁:使用 lock() 或其他加锁方法获取锁。
  3. 执行临界区代码:在持有锁的情况下,执行需要保护的共享资源代码。
  4. 释放锁:使用 unlock() 释放锁,确保其他线程能够继续执行。
import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockDemo {

    private final ReentrantLock lock = new ReentrantLock(); // 创建锁
    private int counter = 0; // 共享资源

    public void increment() {
        lock.lock(); // 获取锁
        try {
            counter++;
            System.out.println(Thread.currentThread().getName() + " - Counter: " + counter);
        } finally {
            lock.unlock(); // 确保在 finally 中释放锁
        }
    }

    public static void main(String[] args) {
        ReentrantLockDemo demo = new ReentrantLockDemo();
        
        Thread t1 = new Thread(demo::increment);
        Thread t2 = new Thread(demo::increment);
        
        t1.start();
        t2.start();
    }
}
2.2 尝试获取锁

使用 tryLock() 可以尝试在不阻塞的情况下获取锁。如果当前锁未被持有,则立即获取并返回 true,否则返回 false。这种方法适合用于避免死锁。

if (lock.tryLock()) {
    try {
        // 执行临界区代码
    } finally {
        lock.unlock();
    }
} else {
    // 锁不可用时的处理逻辑
}

还可以设置超时时间来获取锁,避免线程长时间等待锁:

try {
    if (lock.tryLock(1, TimeUnit.SECONDS)) {
        try {
            // 获取锁后执行的逻辑
        } finally {
            lock.unlock();
        }
    } else {
        // 超时未能获取锁
    }
} catch (InterruptedException e) {
    e.printStackTrace();
}
2.3 可中断锁

lockInterruptibly() 允许线程在等待锁时响应中断。这对于实现中断操作的灵活性非常有用。

try {
    lock.lockInterruptibly(); // 可中断的锁获取
    try {
        // 临界区代码
    } finally {
        lock.unlock();
    }
} catch (InterruptedException e) {
    // 处理中断
    e.printStackTrace();
}
2.4 公平锁与非公平锁

通过构造函数选择锁的公平性:

  • 非公平锁(默认):

    ReentrantLock lock = new ReentrantLock();
    

  • 公平锁:

    ReentrantLock lock = new ReentrantLock(true);
    

公平锁保证线程按顺序获取锁,但性能较低;非公平锁可能导致“饥饿”,但性能更高。

三、ReentrantLock 的内部实现

ReentrantLock 基于 AQS 实现,它通过原子操作 CAS 来控制同步状态。AQS 维护了两个核心状态:

  1. state:表示锁的状态,0 表示未锁定,1 表示锁定。
  2. 线程队列:AQS 使用一个 FIFO 队列来管理等待锁的线程。

当线程尝试获取锁时:

  1. 如果 state == 0,线程成功获取锁,并将 state 设置为 1。
  2. 如果锁已经被持有(state != 0),线程进入等待队列,直到锁释放后被唤醒。

当持有锁的线程调用 unlock() 时,state 被递减。只有当 state 递减到 0 时,锁才真正释放。

四、使用 ReentrantLock 的注意事项

4.1 必须手动释放锁

ReentrantLock 和 synchronized 的主要区别之一是锁的释放必须显式调用 unlock()。忘记释放锁会导致其他线程永远无法获取锁。因此,通常在 try 块中获取锁,在 finally 块中释放锁,以确保异常情况下锁也能被正确释放。

4.2 避免死锁

当多个线程持有多个锁时,容易产生死锁问题。为了避免死锁,可以采用锁的超时机制,或者设计更合理的加锁顺序。

4.3 性能与公平性

非公平锁的性能比公平锁更好,但可能导致某些线程长期无法获得锁。公平锁避免了这种情况,但每次加锁和解锁的性能稍差。在高并发场景下,通常选择非公平锁来提升性能。

4.4 避免锁竞争

过度使用锁可能导致线程竞争和性能下降。在设计多线程应用时,尽量减少临界区的长度,避免不必要的锁。

五、总结

ReentrantLock 提供了比 synchronized 更灵活的锁控制方式。它可以:

  • 选择公平锁和非公平锁;
  • 提供尝试获取锁和可中断的锁;
  • 允许锁的重入;
  • 支持手动加锁和解锁的细粒度控制。
多线程系列(八) -ReentrantLock基本用法介绍 在之前的线程系列文章中,我们介绍到了使用synchronized关键字可以实现线程同步安全的效果,以及采用wait()、notify()和notifyAll()方法,可以实现多个线程之间的通信协调,基本可以满足并发编程的需求。 阅读详情

相关推荐

多线程系列(九) -ReentrantLock常用方法详解

在上一篇文章中,我们介绍了ReentrantLock类的一些基本用法,今天我们重点来介绍一下ReentrantLock其它的常用方法,以便对ReentrantLock类的使用有更深入的理解。

程序员志哥的博客 2352

ReentrantLock详解

ReentrantLock使用,

weixin_56738054的博客 1万+

【多线程】轻松彻底搞懂ReentrantLock的底层实现原理

上篇博客讲解了Sychronized的底层实现原理,它是基于jdk实现的,现在此篇博客讲解基于AQS 框架实现的另一个锁ReentrantLock。

李光 未来科技 1665

ReentrantLock锁

1. 简介 ReentrantLock,可重入锁,是一种递归无阻塞的同步机制。它可以等同于 synchronized 的使用,但是 ReentrantLock 提供了比 synchronized 更强大、灵活的锁机制,可以减少死锁发生的概率

weixin_46121031的博客 7641

告别环境配置烦恼:Docker容器化一站式搭建Zephyr RTOS开发环境

本文详细介绍了如何使用Docker容器化技术一站式搭建Zephyr RTOS开发环境,彻底解决环境配置不一致、依赖冲突等难题。通过预构建镜像、数据卷挂载和实战编译示例,帮助开发者快速获得隔离、一致且可复现的嵌入式开发环境,大幅提升开发效率和团队协作体验。

n8m7b6v5c4的博客 189

告别屏幕闪烁:手把手教你用示波器抓取并分析MIPI DSI信号(以RK平台为例)

本文详细介绍了如何利用示波器抓取并分析MIPI DSI信号,以解决LCD屏幕闪烁、花屏等问题。以RK平台为例,从工具准备、示波器参数配置到信号捕获与波形解读,提供了一套完整的调试方案,帮助硬件工程师快速定位和解决显示接口信号完整性问题。

weixin_33704591的博客 654

方法实现原理_ReentrantLock 原理分析(一)

ReentrantLock 作用ReentrantLock 是一把可重入的排它锁。多线程下,可以保证只有一个线程获取该锁,如果该线程已经获取锁,并且重新尝试获取该锁是可以成功获取的,这就是可重入的概念。他主要用途就是为共享资源提供同步访问的作用。ReentrantLock 使用例子使用方法也很简单,new 一个ReentrantLock 实例,然后掉用lock方法获取锁,使用完毕调用unlock方...

weixin_35054319的博客 217

在 ABAP 平台上搭建 OAuth 2.0 Server:架构、流程、权限与落地实战

摘要:本文为SAP ABAP开发人员提供将ABAP平台配置为OAuth 2.0授权服务器的实战指南。重点介绍两种授权流程(授权码和SAML Bearer)的实现方案,包括核心事务配置(SOAUTH2/SAML2)、授权对象(S_SCOPE)管理以及端点交互规范。通过具体配置清单和三类典型集成场景(第三方Web应用访问OData、企业集成平台调用、BTP应用对接)的落地示例,帮助读者快速构建安全的OAuth 2.0服务架构。文档强调SSL/TLS基础安全、scope最小授权原则以及授权与令牌端点的标准交互模式

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 311

【并发编程】深入理解ReentrantLock使用方法与原理解析(1)

ReentrantLock是Java多线程编程中一款强大的同步工具,具备可重入、公平非公平锁等特性,为多线程程序提供了高度灵活性。深入理解其使用方法和底层原理有助于编写高效、安全的多线程应用。在实际项目中,根据需求选择适当的锁策略,能够更好地发挥ReentrantLock的优势。通过遵循相关指南,可以安全地使用ReentrantLock,避免一些潜在陷阱。在实际应用中,依赖于精心设计和对多线程问题的深刻理解,才能最大程度地发挥ReentrantLock的潜力,帮助读者编写高效、可靠的多线程程序。

龚小帅的博客 1630

Android11原生设置屏幕亮由Gamma变化改为线性变化

从Android9 开始屏幕亮度调解变成非线性变化,这样的话就会出现 之前亮度变化很小,到后面时变化亮度很快; 修改为线性变化,只需要修改 ./frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache L

Android 4926

【论文复现】——基于LM优化的NDT点云配准算法

传统的正态分布变换配准算法处理初始位姿变换相差较大的两帧点云时,存在无法收敛或者陷入局部最小值的问题。为了提高算法的收敛性能,提出了一种基于LM方法改进的三维正态分布变换配准算法。

点云侠的博客 1163

java锁机制(CAS/synchronize/ReentrantLock)的实现原理和使用方法

CAS/synchronized锁/自旋锁

网络安全研究 1684

npm install 时出现npm error code ENOTFOUND和npm error network request to https://registry.npmjs.org的解决方案

本文主要介绍了npm install 时出现npm error code ENOTFOUND和npm error network request to https://registry.npmjs.org 的解决方案,希望能对使用npm的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 6万+

同步方法中的锁对象_ReentrantLock 中 锁和解锁的底层原理浅析

关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析如下代码,当我们在使用 ReentrantLock 进行加锁和解锁时,底层到底是如何帮助我们进行控制的啦? static Lock lock = new ReentrantLock(); public static void main(String[] args) { // 使用...

weixin_34640046的博客 520

基于Jeecgboot3.9.0的vue3版本前后端分离的flowable流程管理平台

基于Jeecgboot3.9.0的vue3版本前后端分离的flowable流程管理平台

宁波阿成的博客 902

上万条对话白分析了?智能客服质检避坑指南:90%团队倒在这些误区

当前客服质检普遍存在投入产出失衡的现象,根源在于十大误区:过度关注单点技术指标而忽视端到端解决能力、僵化的话术模板限制AI应变、数据孤岛阻碍知识进化、盲目追求拟人化牺牲效率、传统整改机制跟不上机器速度等。破局需重构质检体系,包括建立决策树质检法、设计复杂问题测试集、构建实时数据闭环、重置AI专属评价指标、实施分钟级热修复机制等。关键在于将质检从被动纠错升级为主动赋能,通过根因分析、场景化反馈、标准化评分和数据驱动优化,打造"问题诊断-改进-验证"

2202_75469062的博客 1542

【Java核心能力】上万字 ReentrantLock 原理全面详解!

本来写这篇文章是因为自己对 ReentrantLock 的了解一直都比较表面,原理了解的还不是那么的清楚,并且对 AQS 也都是一知半解,但是在面试中这些都是比较常问的内容,如果原理了解比较清楚的话,对面试会有很大的帮助,因此自己在这里也总结了一份,本来以为很快就写完了,没想到竟然写了两天,文字的话就有 6000 +,ReentrantLock 中大部分的内容也都说到了,并且配有许多图片,如果感觉内容太多的话,可以对 ReentrantLock 中加锁以及解锁内容重点阅读,希望对你有所帮助!

qq_45260619的博客 2079

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

ReentrantLock实现原理深入探究

前言 这篇文章被归到Java基础分类中,其实真的一点都不基础。网上写ReentrantLock的使用、ReentrantLock和synchronized的区别的文章很多,研究ReentrantLock并且能讲清楚ReentrantLock的原理的文章很少,本文就来研究一下ReentrantLock的实现原理。研究ReentrantLock的实现原理需要比较好的Java基础以及阅读代码的能...

cnq2328的专栏 317

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

synchronized 和 reentrantlock 区别是什么_synchronized关键字和Lock锁有什么区别

一道非常经典的面试题了,好多次都遇到过,根据这个可以衍生很多其它的面试点,大家也可扩散下思维。实现的原理不同synchronized是关键字,属于JVM层面,是基于Monitor对象实现的同步,每次对锁的获取与释放会带来用户态和内核态之间的切换,非常影响性能,在并发量较高的时候,synchronized性能不高。JDK1.6之后有优化。从JDK1.5,并发包引入Lock锁Lock锁是基于API层面...

weixin_39644139的博客 289

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

关于 ReentrantLock 中锁 lock() 和解锁 unlock() 的底层原理浅析

当我们在使用 ReentrantLock 进行加锁和解锁时,底层到底是如何帮助我们进行控制的啦?带着这样的疑问,我们先后跟进 lock()和unlock() 源码一探究竟。

yanzigejuly的博客 1113

ReentrantLock使用和原理(AQS简述)

在开发过程中,synchronized是最简单的同步控制方法,在通常情况下是够用的,但synchronized时不响应中断,而且有时候,我们需要灵活的来控制加解锁。这时候可以使用ReentrantLock。 在以前的版本中,synchronized效率是远远低于ReentrantLock,后来经过优化,两者性能差距不大了。但ReentrantLock有一些新特性,是synchronized所不具...

永远向前 1503

Java之Reentrantlock的实现及AQS的原理和应用

ReentrantLock意思为可重入锁,指的是一个线程能够对一个临界资源重复加锁。

qq_62592925的博客 1450

Java-ReentrantLock基本使用及底层原理

概述 ReentrantLock相对于synchronized有一下特性: 1:可中断 2:可设置超时时间 3:可设置为公平锁 4:可设置多个条件变量 与synchronized相同的是:都是支持可重入。 可重入 可重入是指一个线程在获得一把锁后,因为它是这把锁的拥有这,所以有权利再次获得这把锁。 但是不可重入是指,线程获得锁后再次想获得锁但是被挡住了! 示例:让主线程连续获得method1...

qq_42411214的博客 1015

从ReentrantLock的实现看AQS的原理及应用

前言 Java中的大部分同步类(Lock、Semaphore、ReentrantLock等)都是基于AbstractQueuedSynchronizer(简称为AQS)实现的。AQS是一种提供了原子式管理同步状态、阻塞和唤醒线程功能以及队列模型的简单框架。本文会从应用层逐渐深入到原理层,并通过ReentrantLock的基本特性和ReentrantLock与AQS的关联,来深入解读AQS相关独占锁的知识点,同时采取问答的模式来帮助大家理解AQS。由于篇幅原因,本篇文章主要阐述AQS中独占锁的逻辑和Sync

上山打卤面的博客 517

Java:Java学习笔记之ReentrantLock的简单理解和使用

ReentrantLock ReentrantLock1、相关知识1.1 公平锁和非公平锁1.2 可重入锁1.3、CAS算法2、背景、定义和特征2.1、背景2.2、定义2.3、特征3、基本结构4、基本使用4.1、解决背景问题4.2、重入锁 使用4.3、公平锁使用5、源码分析5.1、AQS5.2、非公平锁的实现原理5.2.1、lock方法获取锁:tryAcquire5.2.2、锁的释放:tryRelease5.3、公平锁的实现原理5.3.1、lock方法获取锁:tryAcquire5.3.2、锁的释放:try

JMW1407的博客 6990
上一篇: MySQL 的 MVCC机制
下一篇: ReentrantLock 和synchronize比较
yymagicer
博客等级 码龄13年 1425粉丝 180原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yymagicer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值