深入对比:java中Synchronized关键字和ReentrantLock锁的终极对决

Synchronized和ReentrantLock在Java中都是用来控制并发访问共享资源的机制,但它们在获取释放锁的方式、锁的特性以及锁的实现级别等方面存在一些差异。

锁的特性

synchronized是Java的关键字,可以隐式地获取和释放锁。synchronized关键字通过内置的锁机制来控制对共享资源的并发访问,确保每次只有一个线程能够执行被synchronized保护的代码区域。在Java对象头中有关于锁的信息,当一个线程试图获取一个对象的锁时,JVM会进行相应的内存布局调整和优化,以确保线程安全。
ReentrantLock支持公平锁,即等待时间最长的线程会优先获得锁,而synchronized则默认情况下是不公平的。当线程进入synchronized修饰的代码块时,JVM会自动给对象加锁,离开时自动解锁。而ReentrantLock需要开发者手动调用lock()和unlock()方法来获取和释放锁。

synchronized典型代码:

synchronized (ClassName.class) {}

而可重入锁为保证锁释放,每一个 lock() 动作,我建议都立即对应一个 try-catch-finally,典型的代码结构如下:

ReentrantLock fairLock = new ReentrantLock(true);
fairLock.lock();
try {// do something
} finally {fairLock.unlock();
}

ReentrantLock 是一个功能强大且灵活的同步工具,适用于那些需要高度细粒度控制的同步控制的场景。ReentrantLock提供一些api来更好的进行控制:

尝试锁定

你可以使用 tryLock() 方法尝试立即获取锁,如果锁不可用,它将返回 false:

if (lock.tryLock()) {try {// ... 执行线程安全的操作 ...} finally {lock.unlock();}
} else {// 未能获取锁,采取其他措施...
}

还可以指定最长等待时间:

try {if (lock.tryLock(5, TimeUnit.SECONDS)) {try {// ... 执行线程安全的操作 ...} finally {lock.unlock();}} else {// 在指定时间内未获得锁}
} catch (InterruptedException e) {// 当前线程在等待过程中被中断
}

条件变量

使用 newCondition() 方法可以创建与 ReentrantLock 关联的 Condition 实例,条件变量允许线程在不满足特定条件时等待,并在其他线程改变状态后被唤醒:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class ConditionDemo {private Lock lock = new ReentrantLock();private Condition condition = lock.newCondition();public void method1() {try {lock.lock();while (true) {// 等待条件满足condition.await();// 处理业务逻辑System.out.println("method1 is running");}} catch (InterruptedException e) {e.printStackTrace();} finally {lock.unlock();}}public void method2() {try {lock.lock();// 改变条件状态condition.signalAll();} finally {lock.unlock();}}
}

在这个示例中,我们创建了一个 Lock 和一个 Condition 对象。method1() 方法中使用了 while 循环来不断检查条件是否满足,如果条件不满足,就调用 condition.await() 方法让当前线程等待。当条件满足时,线程会被唤醒并继续执行。method2() 方法中改变了条件状态,并调用 condition.signalAll() 方法通知所有正在等待的线程。

抉择

选择synchronized还是ReentrantLock通常取决于以下因素:

  • 简单性 vs. 灵活性:如果你需要简单的线程安全,并且不介意使用JVM内置的锁机制,那么synchronized可能是一个好选择。如果你需要超时、可中断的锁或者公平性保证,那么ReentrantLock是更好的选择。

  • 性能考虑:在高竞争的环境下,ReentrantLock通常比synchronized表现更好,尤其是它的公平锁模式可以减少线程唤醒的开销。

  • 功能需求:如果需要条件变量、尝试非阻塞地获取锁或绑定多个条件,ReentrantLock提供了这些功能,而synchronized则没有。

  • 错误检查:使用ReentrantLock时,如果忘记释放锁,可能会导致死锁。synchronized则由JVM管理,不容易出现这种问题。

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

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

相关文章

vue百度地图的和element输入框/v-region的联动

vue百度地图的使用 第一步:安装插件第二步:main.js中引用第三步:页面中使用 第一步:安装插件 npm install vue-baidu-map --save第二步:main.js中引用 // 百度地图 import BaiduMap from vue-baidu-map Vue.use(Baid…

微信小程序(三十九)表单信息收集

注释很详细&#xff0c;直接上代码 上一篇 新增内容&#xff1a; 1.表单收集的基本方法 2.picker的不足及解决方法 源码&#xff1a; index.wxml <!-- 用户信息 --> <view class"register"><!-- 绑定表单信息收集事件--><form bindsubmit"…

计算两个数相除后的余数返回值为浮点型math.fmod(x, y)

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 计算两个数相除后的余数 返回值为浮点型 math.fmod(x, y) [太阳]选择题 请问以下代码执行math.fmod()后输出的结果是&#xff1f; import math print("【执行】math.fmod(10, 4)"…

sql查询大小写问题

IN() 函数大小敏感判断 如果你在使用 MySQL 的 IN() 函数时发现大小写不敏感&#xff0c;那可能是由于你的 MySQL 数据库的配置设置了大小写不敏感的规则。 这通常是由 lower_case_table_names 参数引起的。在 MySQL 中&#xff0c;这个参数决定了数据库系统在存储和比较表名…

高斯伪谱C++封装库开源!

Windows x64/86 C无依赖运行高斯伪谱法求解最优控制问题&#xff0c;你只需要ElegantGP! Author: Y. F. Zhang His Github: https://github.com/ZYunfeii 写在前面 这个库在你下载它的那一时刻起不再依赖任何其他代码&#xff0c;直接可用来构建C的最优控制问题并进行求解。…

springboot163美食推荐商城的设计与实现

简介 【毕设源码推荐 javaweb 项目】基于springbootvue 的 适用于计算机类毕业设计&#xff0c;课程设计参考与学习用途。仅供学习参考&#xff0c; 不得用于商业或者非法用途&#xff0c;否则&#xff0c;一切后果请用户自负。 看运行截图看 第五章 第四章 获取资料方式 **项…

C++多线程:this_thread 命名空间

std::this_thread 是 C 标准库中提供的一个命名空间&#xff0c;它包含了与当前线程相关的功能。这个命名空间提供了许多与线程操作相关的工具&#xff0c;使得在多线程环境中更容易进行编程。 源码类似于如下&#xff1a; namespace std{namespace this_thread{//...........…

图片加速接口:缓存图片,加速访问,解决防盗链

CSDN会自动把图片存到自己的图床&#xff0c;测试效果不好&#xff0c;建议到 https://www.skyqian.com/archives/speed-up-picture.html 查看效果。 引言 不知道是否有遇到以下场景&#xff1a; 图片打开很慢&#xff01;因为图片源来自于国外。图片可以正常打开&#xff0c…

在C++的union中使用std::string(非POD对象)的陷阱

struct和union的对比 union最开始是C语言中的关键字&#xff0c;在嵌入式中比较常见&#xff0c;由于嵌入式内存比较稀缺&#xff0c;所以常用union用来节约空间&#xff0c;在其他需要节省内存的地方也可以用到这个关键字&#xff0c;写一个简单程序来说明union的用途 struc…

docker 运行jar包 指定配置文件

要在Docker中运行JAR包并指定配置文件&#xff0c;你可以创建一个Dockerfile来定义你的容器环境&#xff0c;并在其中指定如何运行JAR包和配置文件。下面是一个简单的例子&#xff0c;展示了如何在Dockerfile中设置这些配置&#xff1a; 第一步&#xff1a;创建 Dockerfile文件…

第十个知识点:继承

在ES6之后&#xff0c;javascript引入了类的概念&#xff0c;也就是说与java相同&#xff0c;我们可以在js文件中创建类与对象&#xff0c;然后通过extend继承 <script>class Father {constructor(name) {//父类构造器this.name name;}speak(){//父类方法console.log(我…

生成 Python 项目requirements的最小列表

Python项目中的requirements文件 requirements.txt的格式 在Python项目中&#xff0c;通常会包含一个 requirements.txt 文件&#xff0c;其中列出了项目运行所需的Python库及其版本信息。该文件用于部署Python项目的运行环境&#xff0c;并管理项目的依赖包&#xff0c;以确…

java set集合相关介绍和方法使用操作

在Java中&#xff0c;Set是一种不允许元素重复的集合&#xff0c;它是基于哈希表实现的。Set接口继承自Collection接口&#xff0c;常见的实现类有HashSet、LinkedHashSet和TreeSet。 HashSet是基于哈希表实现的Set&#xff0c;它不保证元素的顺序&#xff0c;存储和访问速度较…

Codeforces Round 923 (Div. 3)E. Klever Permutation 找规律,有共同区间

Problem - E - Codeforces 目录 Source of idea: 思路&#xff1a; 代码&#xff1a; 另一个up的找规律的解法&#xff1a; Source of idea: Codeforces Round 923(A-F题解) - 哔哩哔哩 (bilibili.com) 思路&#xff1a; 上面up分析的很好。两个相邻区间也就端点不一样&…

nginx限制网段访问

文章目录 nginx限制网段访问介绍:使用:示例:介绍网段:nginx限制网段访问 介绍: Nginx的deny和allow指令是由ngx_http_access_module模块提供, Nginx安装默认内置了该模块 使用: nginx访问控制模块: 想禁止哪个ip访问就加上deny IP, 想允许哪个ip访问就加上allow…

使用Pillow来生成简单的红包封面

Pillow库&#xff08;Python Imaging Library的后继&#xff09;是一个强大而灵活的图像处理库&#xff0c;适用于Python。Pillow 库&#xff08;有时也称 PIL 库&#xff09; 是 Python 图像处理的基础库&#xff0c;它是一个免费开源的第三方库&#xff0c;由一群 Python 社区…

List与数组相互转换

文章目录 将 List 转 数组List.toArra()Stream().toArray() 将 数组 转 ListLists.newArrayList()Stream.of() 将 List 转 数组 List.toArra() List<Integer> list Lists.newArrayList(1, 2, 3);// 无需转换类型 --> [1,2,3]Integer[] intArray list.toArray(new I…

掌握Python爬虫的四大组件之Handler(处理器)

源码分享 https://docs.qq.com/sheet/DUHNQdlRUVUp5Vll2?tabBB08J2 在构建高效的Python爬虫时&#xff0c;理解和应用日志组件是至关重要的。在前一章节中&#xff0c;我们探讨了Logger&#xff08;记录器&#xff09;的概念和基础用法。本章节&#xff0c;我们将聚焦于Logge…

2024年Java架构篇之设计模式

2024年Java实战面试题_java 5 年 面试-CSDN博客 1、单例模式

IAR报错:Error[Pa045]: function “halUartInit“ has no prototype

在IAR工程.c文件末尾添加一个自己的函数&#xff0c;出现了报错Error[Pa045]: function "halUartInit" has no prototype 意思是没有在开头添加函数声明&#xff0c;即void halUartInit(void); 这个问题我们在keil中不会遇到&#xff0c;这是因为IAR编译器规则的一…