大厂高频面试题:ReentrantLock 与 synchronized异同点对比

写在开头

在过去的博文中我们学习了ReentrantLock 与 synchronized这两种Java并发使用频率最高的同步锁,在很多大厂面试题中有个经典考题:

ReentrantLock 与 synchronized异同点对比!

今天我们针对这一考题来做一个尽可能全面的总结哈。

ReentrantLock 与 synchronized

ReentrantLock是一种独占式的可重入锁,位于java.util.concurrent.locks中,是Lock接口的默认实现类,底部的同步特性基于AQS实现,和synchronized关键字类似,但更灵活、功能更强大、也是目前实战中使用频率非常高的同步类。

synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API

synchronized 是依赖于 JVM 实现的,虚拟机团队在 JDK1.6 为 synchronized 关键字进行了很多优化,但是这些优化都是在虚拟机层面实现的,并没有直接暴露给我们。

ReentrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成),ReentrantLock 比 synchronized 增加了一些高级功能。

区别罗列

  1. ReentrantLock 是一个类,而 synchronized 是 Java 中的关键字;
  2. ReentrantLock 必须手动释放锁。通常需要在 finally 块中调用 unlock 方法以确保锁被正确释放;
  3. ReentrantLock可以指定是公平锁还是非公平锁。而synchronized只能是非公平锁。所谓的公平锁就是先等待的线程先获得锁;
  4. synchronized 会自动释放锁,当同步块执行完毕时,由 JVM 自动释放,不需要手动操作;
  5. ReentrantLock 可以实现多路选择通知(可以绑定多个 Condition),而 synchronized 只能通过 wait 和 notify/notifyAll 方法唤醒一个线程或者唤醒全部线程(单路通知);
  6. ReentrantLock提供了一种能够中断等待锁的线程的机制,通过 lock.lockInterruptibly() 来实现这个机制。也就是说正在等待的线程可以选择放弃等待,改为处理其他事情。而synchronized不具备这种特点。
  7. ReentrantLock: 通常提供更好的性能,特别是在高竞争环境下;
  8. synchronized: 在某些情况下,性能可能稍差一些,但随着 JDK 版本的升级,性能差距已经不大了。

【注】:Condition是 JDK1.5 之后才有的,它具有很好的灵活性,比如可以实现多路通知功能也就是在一个Lock对象中可以创建多个Condition实例(即对象监视器),线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知,在调度线程上更加灵活,我们在后面的学习中会耽误聊一聊它!

性能对比

虽然说JDK1.6后synchronized的性能有很大的提升了,但是相比较而言,两者之间仍然存在性能差别,我们通过一个小demo来测试一下。

public class Test {private static final int NUM_THREADS = 10;private static final int NUM_INCREMENTS = 1000000;private int count1 = 0;private int count2 = 0;private final ReentrantLock lock = new ReentrantLock();private final Object syncLock = new Object();public void increment1() {lock.lock();try {count1++;} finally {lock.unlock();}}public void increment2() {synchronized (syncLock) {count2++;}}public static void main(String[] args) throws InterruptedException {Test test = new Test();// ReentrantLock性能测试long startTime = System.nanoTime();Thread[] threads = new Thread[NUM_THREADS];for (int i = 0; i < NUM_THREADS; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < NUM_INCREMENTS; j++) {test.increment1();}});threads[i].start();}for (Thread thread : threads) {thread.join();}long endTime = System.nanoTime();System.out.println("ReentrantLock完成时间: " + (endTime - startTime) + " ns");// synchronized性能测试startTime = System.nanoTime();for (int i = 0; i < NUM_THREADS; i++) {threads[i] = new Thread(() -> {for (int j = 0; j < NUM_INCREMENTS; j++) {test.increment2();}});threads[i].start();}for (Thread thread : threads) {thread.join();}endTime = System.nanoTime();System.out.println("synchronized完成时间: " + (endTime - startTime) + " ns");}
}

我们采用10个线程,每个线程做加1000000操作,执行时间对比如下:

//1000000万数据量时
ReentrantLock完成时间: 272427700 ns
synchronized完成时间: 675759100 ns
//10000数据量时
ReentrantLock完成时间: 52207600 ns
synchronized完成时间: 11291600 ns

很明显在数据量比较大的时候,竞争激烈时,ReentrantLock的性能要比synchronized好很多,但在数据量较低的情况下,会呈现出不同的结果。

结尾彩蛋

如果本篇博客对您有一定的帮助,大家记得留言+点赞+收藏呀。原创不易,转载请联系Build哥!

在这里插入图片描述
如果您想与Build哥的关系更近一步,还可以关注“JavaBuild888”,在这里除了看到《Java成长计划》系列博文,还有提升工作效率的小笔记、读书心得、大厂面经、人生感悟等等,欢迎您的加入!

在这里插入图片描述

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

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

相关文章

UML/SysML建模工具更新情况-截至2024年4月(1)5款-Trufun建模平台 v2024

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集 工具最新版本&#xff1a;itemis CREATE 5.2.2 更新时间 2024年3月22日 工具简介 原名YAKINDU Statechart Tools。状态机建模工具&#xff0c;支持各种语言的代码生成&#xff0c;提…

B2024 输出浮点数 洛谷题单

首选需要进行了解的就是%a.bf所代表的含义就行了&#xff0c;直接莽了&#xff0c;没啥解释的笑脸&#x1f644; 在 Python 中&#xff0c;%a.bf 中的参数 a 和 b 是用来格式化浮点数的输出的&#xff0c;具体含义如下&#xff1a; a 表示总输出宽度&#xff0c;包括小数点、…

链表基础4——带头双向循环链表(c语言实现)

什么是带头双向循环链表 我们直接看图片 定义结点类型 typedef int LTDataType;//存储的数据类型typedef struct ListNode {LTDataType data;//数据域struct ListNode* prev;//前驱指针struct ListNode* next;//后继指针 }ListNode;链表的初始化 //创建一个新结点 ListNod…

什么是反向 ETL?为什么它很有价值?

提取、转换、加载 &#xff08;ETL&#xff09; 过程已经成熟并被广泛采用。 它只涉及从各种源系统中获取数据&#xff0c;将其转换为标准化数据模型&#xff0c;然后将其加载到数据仓库中。从那里&#xff0c;您的团队使用其商业智能 &#xff08;BI&#xff09; 和分析工具中…

FPGA - ZYNQ Cache一致性问题

什么是Cache&#xff1f; Cache是一种用来提高计算机运行速度的一种技术。它是一种小而快的存储设备&#xff0c;位于CPU与内存之间&#xff0c;用于平衡高速设备与低速设备之间的速度差异。Cache可以存储常用的数据或指令&#xff0c;以便CPU更快地获取&#xff0c;从而减少对…

基于单片机的智能病床呼叫系统设计与仿真

摘 要 本文设计的病床呼叫系统采用单片机作为控制器。该系统具有远程控制、病人的身体情况检测、报警呼叫、显示和执行器运动的功能。远程控制由红外线传感器和矩阵键盘组成&#xff0c;检测电路由温湿度传感器DH22、心率传感器Pulse Sensor、压力传感器MPX4115组成&#x…

操作系统——进程

进程定义 是计算机中已经运行的程序是系统进行资源分配和调度的一个独立单位。 进程的特性 独立性&#xff1a;进程在内存中可以独立寻址&#xff0c;每个进程都有一个独立的堆栈空间。动态性&#xff1a;进程在执行过程中可以申请资源、使用资源、释放资源。并发性&#xf…

OceanBase开发者大会2023届视频及PPT汇总

数据库技术趋势 我眼中的数据库技术 阳振坤OceanBase 首席科学家 观看视频 下载 PDF 未来&#xff0c;中国需要什么样的数据库&#xff1f; 周傲英华东师范大学副校长&#xff0c;CCF 会士 观看视频 下载 PDF 云原生技术趋势解读 Keith ChanCNCF 云原生计算基金会中国区总监 …

批量规范化(batchnormalization)

ˆB 是小批量B的样本均值&#xff0c;σˆ B 是小批量B的样本标准差。应用标准化后&#xff0c;生成的小批量的平均 值为0和单位方差为1。由于单位方差&#xff08;与其他一些魔法数&#xff09;是一个主观的选择&#xff0c;因此我们通常包含 拉伸参数&#xff08;scale&#…

Linux关闭swap分区操作[适用于CDH报警等]

1.查看swap分区挂载路径(没卵用) swapon -s 2.设置配置文件的swap配置 echo “vm.swappiness 0” > /etc/sysctl.conf 3.设置内存中的swap状态。有时候配置文件为0&#xff0c;但集群或服务仍然使用了swap分区&#xff0c;可能原因就是内存没有同步配置 echo “0” > …

【配电网故障定位】基于二进制蝙蝠算法的配电网故障定位 33节点配电系统故障定位【Matlab代码#80】

文章目录 【获取资源请见文章第6节&#xff1a;资源获取】1. 配电网故障定位2. 二进制蝙蝠算法3. 算例展示4. 部分代码展示5. 仿真结果展示6. 资源获取 【获取资源请见文章第6节&#xff1a;资源获取】 1. 配电网故障定位 配电系统故障定位&#xff0c;即在配电网络发生故障的…

微信有关白名单IP

一、商家支付 二、公众号