news 2026/4/13 13:14:12

深入解析Java中的可重入锁ReentrantLock

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
深入解析Java中的可重入锁ReentrantLock

文章目录

  • 深入解析Java中的可重入锁ReentrantLock
    • 一、什么是ReentrantLock?
    • 二、为什么要用ReentrantLock?
    • 三、ReentrantLock的核心特性
      • 1. **可重入性**
      • 2. **公平性和非公平性**
      • 3. **锁的状态**
    • 四、ReentrantLock vs synchronized
    • 五、ReentrantLock的使用场景
      • 1. 高并发场景
      • 2. 公平性要求高的场景
      • 3. 需要可重入性的场景
    • 六、ReentrantLock的注意事项
      • 1. **避免死锁**
      • 2. **防止资源泄漏**
      • 3. **避免使用过多的锁**
    • 七、实战案例:实现一个简单的银行转账
      • 案例描述:
      • 实现代码:
      • 分析:
    • 八、总结
    • 希望这篇长文能帮助你更好地理解和使用ReentrantLock!如果还有疑问或者想深入探讨的地方,欢迎随时交流。
      • 📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

深入解析Java中的可重入锁ReentrantLock

各位朋友们大家好!闫工又来给大家讲技术了!这次我们来聊一聊Java中一个非常重要的同步工具——ReentrantLock(可重入锁)。相信很多小伙伴在学习Java多线程的时候,或多或少都听说过这个词。但是,你真的搞懂它是什么、怎么用以及它的那些“小心机”吗?别急,闫工带着你们一步步深入,手把手教会你!


一、什么是ReentrantLock?

首先,让我们从基础开始。ReentrantLock是Java中一个非常强大的锁机制,属于java.util.concurrent.locks包。它主要用于在多线程环境下控制对共享资源的访问,避免多个线程同时修改或读取同一块数据时出现混乱。

ReentrantLock的名字中有两个关键词:

  1. Reentrant:意思是“可重入”的,表示同一个线程可以多次获取同一个锁。
  2. Lock:当然就是锁的意思啦!

简单来说,ReentrantLock就是一个能够被多个线程共享、并且支持公平与非公平模式的高级锁机制。


二、为什么要用ReentrantLock?

在Java中,默认的同步方式是synchronized关键字。虽然synchronized非常简单易用,但它也有一些缺点:

  1. 粒度控制不够细:无法实现更复杂的锁逻辑。
  2. 性能问题:在某些场景下,synchronized的表现不如显式的锁机制。
  3. 缺乏公平性支持:默认情况下,synchronized是不公平的。

而ReentrantLock则弥补了这些不足。它提供了更多的灵活性和控制力,比如:

  • 支持可重入(同一个线程可以多次加锁)。
  • 可以选择公平或非公平的锁获取方式。
  • 提供条件队列(Condition),可以实现更复杂的同步逻辑。

三、ReentrantLock的核心特性

1.可重入性

“可重入”是ReentrantLock的最大特色之一。它允许同一个线程多次获得同一个锁,而不会出现死锁的情况。例如:

publicclassReentrantTest{privatefinalReentrantLocklock=newReentrantLock();publicvoidmethodA(){lock.lock();try{System.out.println("methodA acquire lock");methodB();}finally{lock.unlock();}}publicvoidmethodB(){lock.lock();try{System.out.println("methodB acquire lock");}finally{lock.unlock();}}publicstaticvoidmain(String[]args){ReentrantTesttest=newReentrantTest();test.methodA();}}

在这个例子中,methodA()调用了methodB(),而两者都尝试获取同一个锁。如果没有可重入性,第二次lock.lock()会阻塞甚至导致死锁。但ReentrantLock支持这一点,所以程序可以正常运行。

2.公平性和非公平性

ReentrantLock有两个模式:公平锁非公平锁。默认情况下是非公平锁,即先到的线程不一定能优先获取锁。

  • 非公平锁:当一个线程尝试获取锁时,如果锁是可用的,则立即获得;否则,排队等待。
  • 公平锁:严格按照线程到达的顺序来分配锁,先进先得。

可以通过构造函数指定模式:

// 非公平锁(默认)ReentrantLocklock=newReentrantLock();// 公平锁ReentrantLockfairLock=newReentrantLock(true);

3.锁的状态

ReentrantLock内部维护了一个计数器,用来记录锁的重入次数。每次成功加锁,计数器递增;每次成功解锁,计数器递减。

publicclassLockState{privatefinalReentrantLocklock=newReentrantLock();publicvoidcheck(){System.out.println("Lock hold count: "+lock.getHoldCount());System.out.println("Number of waiting threads: "+lock.getQueueLength());}publicstaticvoidmain(String[]args){LockStatestate=newLockState();state.check();}}

getHoldCount()返回当前线程对锁的持有次数,而getQueueLength()返回正在等待获取该锁的线程数。


四、ReentrantLock vs synchronized

很多人可能会问:既然有了synchronized,为什么还要用ReentrantLock?其实两者的区别还是挺大的:

特性ReentrantLocksynchronized
可重入性支持不支持
公平性选择可选(公平/非公平)
锁粒度控制更灵活较粗粒度
性能在高并发场景下通常更优简单场景表现较好
显式unlock()方法必须手动调用自动管理

五、ReentrantLock的使用场景

1. 高并发场景

在高并发系统中,ReentrantLock的性能和灵活性使其成为首选。例如:

  • 热点数据的读写操作。
  • 复杂的业务逻辑需要更精细的锁控制。

2. 公平性要求高的场景

如果你需要严格的线程调度顺序(比如银行转账中的排队),可以使用公平锁。

3. 需要可重入性的场景

在方法嵌套调用中,如果多个方法都需要加锁,ReentrantLock的可重入性可以避免死锁问题。


六、ReentrantLock的注意事项

1.避免死锁

虽然ReentrantLock支持可重入性,但如果使用不当,仍然可能导致死锁。例如:

publicclassDeadlock{privatefinalReentrantLocklockA=newReentrantLock();privatefinalReentrantLocklockB=newReentrantLock();publicvoidmethodA(){lockA.lock();try{// 一些操作methodB();}finally{lockA.unlock();}}publicvoidmethodB(){lockB.lock();try{// 一些操作methodA();}finally{lockB.unlock();}}}

如果methodA()methodB()同时持有锁,可能会导致死锁。因此,在设计锁的使用顺序时要格外小心。

2.防止资源泄漏

忘记释放锁会导致资源泄漏,从而引发严重的问题。所以一定要在finally块中释放锁:

lock.lock();try{// 执行业务逻辑}finally{lock.unlock();}

3.避免使用过多的锁

虽然ReentrantLock功能强大,但过度使用会导致系统性能下降。要合理设计锁的粒度,尽量减少锁的持有时间。


七、实战案例:实现一个简单的银行转账

为了让大家更好地理解ReentrantLock的应用场景,我们来写一个小例子——银行转账。

案例描述:

两个账户A和B,各有一定金额。我们需要从A转100元到B,并确保整个过程是线程安全的。

实现代码:

publicclassBankTransfer{privatefinalReentrantLocklock=newReentrantLock();privateMap<String,Integer>accounts=newHashMap<>();publicBankTransfer(){accounts.put("A",1000);accounts.put("B",500);}publicvoidtransfer(Stringfrom,Stringto,intamount){lock.lock();try{if(accounts.get(from)>=amount){accounts.put(from,accounts.get(from)-amount);accounts.put(to,accounts.get(to)+amount);System.out.println("Transfer completed. From: "+from+", To: "+to+", Amount: "+amount);}else{System.out.println("Insufficient balance in account "+from);}}finally{lock.unlock();}}publicstaticvoidmain(String[]args){BankTransfertransfer=newBankTransfer();// 创建多个线程进行转账操作for(inti=0;i<5;i++){finalintamount=100;newThread(()->transfer.transfer("A","B",amount)).start();}}}

分析:

  • 我们使用ReentrantLock来保证转账操作的原子性。
  • 每次转账前,先检查账户余额是否足够,然后进行扣款和入账。
  • 使用finally块确保锁总是被释放。

八、总结

  • ReentrantLock是一个功能强大的锁工具,支持可重入性和公平性选择。
  • 在高并发场景下,它比synchronized更灵活且性能更好。
  • 使用时需要注意避免死锁和资源泄漏问题,并合理设计锁的粒度。

希望这篇长文能帮助你更好地理解和使用ReentrantLock!如果还有疑问或者想深入探讨的地方,欢迎随时交流。

📚 领取 | 1000+ 套高质量面试题大合集(无套路,闫工带你飞一把)!

成体系的面试题,无论你是大佬还是小白,都需要一套JAVA体系的面试题,我已经上岸了!你也想上岸吗?

闫工精心准备了程序准备面试?想系统提升技术实力?闫工精心整理了1000+ 套涵盖前端、后端、算法、数据库、操作系统、网络、设计模式等方向的面试真题 + 详细解析,并附赠高频考点总结、简历模板、面经合集等实用资料!

✅ 覆盖大厂高频题型
✅ 按知识点分类,查漏补缺超方便
✅ 持续更新,助你拿下心仪 Offer!

📥免费领取👉 点击这里获取资料

已帮助数千位开发者成功上岸,下一个就是你!✨

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/9 10:52:00

WebGL流体模拟完整实战:从零部署到GitHub Pages的终极指南

WebGL流体模拟完整实战&#xff1a;从零部署到GitHub Pages的终极指南 【免费下载链接】WebGL-Fluid-Simulation Play with fluids in your browser (works even on mobile) 项目地址: https://gitcode.com/gh_mirrors/web/WebGL-Fluid-Simulation 想要在浏览器中体验令…

作者头像 李华
网站建设 2026/4/3 4:44:36

Langchain-Chatchat在医药研发中的价值:文献智能摘要与查询

Langchain-Chatchat在医药研发中的价值&#xff1a;文献智能摘要与查询 在新药研发的征途上&#xff0c;科研人员每天面对的是成千上万页的学术论文、专利文件和实验报告。这些资料不仅数量庞大&#xff0c;而且高度专业化——一个靶点可能关联上百篇文献&#xff0c;每篇又包含…

作者头像 李华
网站建设 2026/4/9 6:37:53

YOLOv7性能优化实战:从理论到部署的完整指南

YOLOv7性能优化实战&#xff1a;从理论到部署的完整指南 【免费下载链接】yolov7 YOLOv7 - 实现了一种新的实时目标检测算法&#xff0c;用于图像识别和处理。 项目地址: https://gitcode.com/GitHub_Trending/yo/yolov7 在实际目标检测项目中&#xff0c;如何快速评估和…

作者头像 李华
网站建设 2026/4/9 10:05:52

Langchain-Chatchat是否依赖外部API?纯本地部署可行性验证

Langchain-Chatchat 是否依赖外部 API&#xff1f;纯本地部署可行性深度验证 在企业对数据安全要求日益严苛的今天&#xff0c;一个看似简单却至关重要的问题浮出水面&#xff1a;我们能否在不把任何敏感信息上传到云端的前提下&#xff0c;构建一套真正智能的知识问答系统&…

作者头像 李华
网站建设 2026/4/9 17:54:55

ghettoVCB:ESXi虚拟机备份的终极解决方案

ghettoVCB&#xff1a;ESXi虚拟机备份的终极解决方案 【免费下载链接】ghettoVCB ghettoVCB 项目地址: https://gitcode.com/gh_mirrors/gh/ghettoVCB 在虚拟化环境中&#xff0c;数据备份是确保业务连续性的关键环节。ghettoVCB作为一款专为VMware ESXi设计的开源备份工…

作者头像 李华
网站建设 2026/4/8 19:18:47

【独家披露】头部金融企业Open-AutoGLM合规落地的4个关键决策

第一章&#xff1a;Open-AutoGLM企业级部署合规改造方案概述在企业级AI系统部署中&#xff0c;模型的合规性、安全性与可维护性成为核心考量。Open-AutoGLM作为一款基于开源大语言模型构建的自动化生成平台&#xff0c;其原始架构虽具备强大推理能力&#xff0c;但在数据隐私保…

作者头像 李华