Java ReentrantLock 详解

news/2025/2/10 5:33:32/文章来源:https://www.cnblogs.com/szz1/p/18707024

简介

在并发编程中,线程同步是一个极其重要的话题。Java 提供了多种机制来帮助开发者管理多线程环境下的资源共享问题,其中 ReentrantLockjava.util.concurrent.locks 包中的一个重要类。相比早期的 synchronized 关键字,ReentrantLock 提供了更为灵活的锁机制,是在高并发场景中优雅解决线程间竞争问题的利器。

目录

  1. 基础概念
  2. 使用方法
  3. 常见实践
  4. 最佳实践
  5. 小结
  6. 参考资料

基础概念

ReentrantLock 是一个可重入的互斥锁,它与 synchronized 同步块类似,但是提供了更多的高级功能。

主要特性

  • 可重入性: 一个线程可以多次获取同一个锁,而不会发生死锁。
  • 公平性: ReentrantLock 可以配置为公平锁和非公平锁,公平锁按照请求锁的顺序分配,而非公平锁则可能让某些线程长时间得不到锁。
  • 可中断锁请求: 在等待锁的过程中,线程可以放弃尝试并响应中断。
  • 超时功能: 可以设定获取锁的时间限制,避免无限等待。
  • 条件变量: 提供了类似于 Objectwait/notify 机制,通过 Condition 类来实现更复杂的线程间同步。

使用方法

使用 ReentrantLock 时,通常遵循“锁-尝试-释放”的模式。下面是一个简单的示例:

import java.util.concurrent.locks.ReentrantLock;public class ReentrantLockExample {private final ReentrantLock lock = new ReentrantLock();public void performTask() {lock.lock();  // 获取锁try {// 临界区代码System.out.println("锁内执行任务");} finally {lock.unlock();  // 释放锁}}public static void main(String[] args) {ReentrantLockExample example = new ReentrantLockExample();Thread t1 = new Thread(example::performTask);Thread t2 = new Thread(example::performTask);t1.start();t2.start();}
}

公平锁和非公平锁

创建 ReentrantLock 实例时,可以选择其公平性:

ReentrantLock fairLock = new ReentrantLock(true);  // 公平锁
ReentrantLock nonFairLock = new ReentrantLock(false);  // 非公平锁

可响应中断的锁

try {lock.lockInterruptibly();// 执行任务
} catch (InterruptedException e) {// 响应中断
} finally {lock.unlock();
}

超时功能

try {if (lock.tryLock(1, TimeUnit.SECONDS)) {try {// 锁内代码} finally {lock.unlock();}} else {// 锁获取失败}
} catch (InterruptedException e) {// 处理中断
}

常见实践

多条件变量

ReentrantLock 可以创建多个 Condition 实例,分别控制不同的线程状态:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;public class MultiConditionExample {private final ReentrantLock lock = new ReentrantLock();private final Condition condition1 = lock.newCondition();private final Condition condition2 = lock.newCondition();public void awaitCondition1() throws InterruptedException {lock.lock();try {condition1.await();// condition1 被唤醒后执行的代码} finally {lock.unlock();}}public void signalCondition1() {lock.lock();try {condition1.signal();} finally {lock.unlock();}}public void awaitCondition2() throws InterruptedException {lock.lock();try {condition2.await();} finally {lock.unlock();}}public void signalCondition2() {lock.lock();try {condition2.signal();} finally {lock.unlock();}}
}

重入锁的嵌套使用

由于 ReentrantLock 是可重入的,同一线程可以在持有锁后再次获取锁,而不会被阻塞:

public void reentrantLockTest() {lock.lock();try {// 第一次获取锁lock.lock();try {// 第二次获取锁} finally {lock.unlock();}} finally {lock.unlock();}
}

最佳实践

  1. 确保最终释放锁: 每次获取锁后一定要在 finally 块中释放,以防止异常情况下锁未释放。

  2. 优先使用 tryLock: 在可能锁竞争比较激烈的代码区域,建议使用 tryLock 以避免死锁。

  3. 选择合适的锁策略: 根据生产环境的需求,选择合适的公平性策略。对于高竞争情况,非公平锁一般性能更好,但可能导致某些线程饥饿。

  4. 条件变量的正确使用: 避免产生假唤醒,使用条件变量时通常需要在循环中等待。

小结

ReentrantLock 为 Java 开发者提供了更为强大的同步控制机制,相比于传统的 synchronized,它提供了可中断锁、超时锁、条件变量等功能,有效提升了并发程序的灵活性和性能。理解其实现原理并结合最佳实践,能够帮助开发者在高并发的编程场景下编写出更加健壮和高效的代码。

参考资料

  1. Java Docs: ReentrantLock
  2. 《Java 并发编程实战》——Brian Goetz
  3. 《Effective Java》第三版——Joshua Bloch
  4. Java线程池
  5. Java 线程同步
    通过这篇博客,希望能帮助读者更加深入地理解 ReentrantLock,并能够在实际工作中灵活运用其功能组件实现高效并发编程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/881521.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

护眼神器!LightBulb电脑屏幕护眼软件,你值得拥有!

点击上方蓝字关注我 前言 LightBulb是一个免费的护眼软件,它可以帮助我们在晚上或长时间看电脑屏幕时,减少眼睛的不舒服和疲劳。这个软件会随着一天时间的推移,自动调整电脑屏幕的颜色。比如,在白天,它会让屏幕颜色更偏向冷蓝色,就像阳光下的颜色;到了晚上,它会让屏幕颜…

【JWT安全】攻防指南全面梳理

一、简单介绍 JWT(JSON Web Token)是一种用于身份认证和授权的开放标准,它通过在网络应用间传递被加密的JSON数据来安全地传输信息使得身份验证和授权变得更加简单和安全,JWT对于渗透测试人员而言可能是一种非常吸引人的攻击途径,因为它们不仅是让你获得无限访问权限的关键而…

【CodeForces训练记录】Codeforces Round 1003 (Div. 4)

训练情况赛后反思 题面读的有点疑惑,怀疑自己阅读理解不大行了,简单题狂WA,C2二分调半天没出,水平严重退步 A题 最后两个字母 us 换成 i点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;void solve(){string s;…

[流程图/技术调研] drawio : 流程图绘制工具

引言 流程图绘制工具: draw.io 简介urlhttps://www.drawio.com/ (官网首页) https://github.com/jgraph/drawio (github)【官网简介】 drawio 这个项目,是一个可配置的图表/白板可视化应用程序。drawio 是由 JGraph Ltd 和 draw AG 共同拥有和开发的。 在运行这个项目的同时,…

国家中小学智慧教育平台新教材及音频下载神器

点击上方蓝字关注我 前言 国家中小学智慧教育平台是一个专门给老师、孩子们提供学习资源的网站,上面有很多专业的教学视频、课件和教材。不过,这些学习资料都只能在网上看,如果没有网络就连不上了。 而这个下载器的作用就像是一个“搬运工”,它可以把这些网上的视频、课件和…

【牛客训练记录】牛客周赛 Round 80

训练情况赛后反思 玩了一两天发现自己水平直接下降一个档次,简单的C题模拟没写出来 A题 直接判断剩下还能放几个棋子,如果小于零就无法放置,否则直接输出即可点击查看代码 #include <bits/stdc++.h> // #define int long long #define endl \nusing namespace std;voi…

【蓝桥训练记录】第 26 场 蓝桥入门赛

训练情况赛后反思 唐完了,二分没看出来 A题 字母排序点击查看代码 #include <iostream> using namespace std; int main() {cout<<"aekns";return 0; }B题 统计两个字符串中 01 的数量,异或找两个不同的数字的出现次数取最小值,再求和即可点击查看代码…

手把手教你一招永久解决DeepSeek服务器繁忙!

前几天A梦分享过DeepSeek的三种使用方式:移动应用APP、网页版本和本地部署。由于DeepSeek的用户数量庞大,导致请求频次较高,用户常常会遇到"服务器繁忙,请稍后重试"的提示。而选择本地部署则可以避免这种问题,并且支持离线使用。正因如此,官方推荐用户选择本地…

[AI/GPT] AI大模型的基础概念

概述:AI大模型 基础概念 幻觉现象 = 一本正经胡说八道AI幻觉,是指大语言模型【编造】它认为是真实存在的、甚至看起来合理或可信的信息。 大模型出现幻觉,简而言之就是“胡说八道”。 准确而言,是指模型生成的内容与现实世界事实或用户输入不一致的现象。 研究人员将大模型…

Nacos的应用案例实战

作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任。 目录一.Nacos实现服务注册和发现实战案例1.部署Nacos集群2.运行服务提供者的JAVA应用2.1 安装JDK2.2 安装Maven2.3 解压准备好的JAVA示例应用2.4 查看Nacos服务相关配置是否正确信息2.5 编译JAVA代码2.6 运行…

前端如何判断浏览器 AdBlock/AdBlock Plus(最新版)广告屏蔽插件已开启拦截

前端如何判断浏览器 AdBlock/AdBlock Plus(最新版)广告屏蔽插件已开启拦截2个月前AdBlock/AdBlock Plus疑似升级了一次因为自己主要负责面对海外的用户项目,发现以前的检测AdBlock/AdBlock Plus开启状态方法已失效了,于是专门研究了一下。并尝试了很多方法。 已失效的老方法…

[Whole Web] 前端项目规范 -- 4. Git提交信息规范(Commitlint + commitizen + cz-git)

前面讲的都是在git提交之前的一些流程检查,而当我们git提交的时候,提交信息,也应该是需要规范的 commitlint 在使用Git提交代码时,通常都需要填写提交说明,也就是Commit Message git commit -m 提交测试说白了,Commit Message就是我们提交的时候,在-m后面写的提交说明,…