news 2026/6/9 16:11:02

深入解析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/6/8 12:01:43

DeepLabCut终极指南:零代码实现专业级动物行为分析

DeepLabCut终极指南&#xff1a;零代码实现专业级动物行为分析 【免费下载链接】DeepLabCut Official implementation of DeepLabCut: Markerless pose estimation of user-defined features with deep learning for all animals incl. humans 项目地址: https://gitcode.com…

作者头像 李华
网站建设 2026/6/10 1:38:15

【数据安全必修课】:Open-AutoGLM个性化隐私配置的7个关键步骤

第一章&#xff1a;Open-AutoGLM隐私配置的核心价值在人工智能模型日益普及的背景下&#xff0c;数据隐私与安全成为开发者和企业关注的重点。Open-AutoGLM 作为一款支持自动化生成与推理的开源语言模型框架&#xff0c;其隐私配置机制不仅保障了用户数据的机密性&#xff0c;还…

作者头像 李华
网站建设 2026/6/9 22:01:57

终极KIMI AI对话系统部署指南:轻松搭建免费智能助手

还在为昂贵的AI服务费用发愁吗&#xff1f;想要拥有一个完全免费的智能对话系统吗&#xff1f;今天我要分享一个实战经验&#xff0c;教大家如何快速部署KIMI AI逆向API&#xff0c;打造属于你自己的免费AI对话系统。作为一个长期关注AI技术的开发者&#xff0c;我亲身体验了KI…

作者头像 李华
网站建设 2026/6/10 10:15:24

Langchain-Chatchat项目贡献指南:如何参与开源社区建设

Langchain-Chatchat 项目贡献指南&#xff1a;如何参与开源社区建设 在企业智能化转型的浪潮中&#xff0c;一个日益突出的问题摆在面前&#xff1a;我们能否在不牺牲数据安全的前提下&#xff0c;让大语言模型真正理解公司内部的知识体系&#xff1f;许多组织尝试使用公有云 …

作者头像 李华
网站建设 2026/6/7 18:53:23

Langchain-Chatchat问答系统冷启动问题解决策略

Langchain-Chatchat问答系统冷启动问题解决策略 在企业智能化转型的浪潮中&#xff0c;知识管理正从“静态归档”走向“动态服务”。越来越多公司希望员工能像问人一样快速获取内部政策、产品参数或合同条款&#xff0c;但现实却常常是&#xff1a;提问得不到回应&#xff0c;搜…

作者头像 李华