当前位置: 首页 > news >正文

synchronized 、volatile 以及 ReentrantLockReentrantLock 的区别

一、synchronized 和 volatile 的区别

synchronized 关键字和 volatile 关键字是两个互补的存在。

  • volatile 关键字是线程同步的轻量实现,所以 volatile 性能比 synchronized 关键字要好。但是 volatile 关键字只能用于修饰变量,而 synchronized 关键字可用于修饰方法以及代码块。
  • volatile 关键字能保证数据的可见性,但不能保证数据的原子性。synchronized 关键字两者都可以保证。
  • volatile 关键字主要用于解决变量在多个线程之间的可见性,而 synchronized 关键字解决的是多个线程之间访问资源的同步性。

二、synchronized 和 ReentrantLock 的区别

2.1 ReentrantLock 是什么?

ReentrantLock 实现了 Lock 接口,是一个可重入且独占式的锁,和 synchronized 关键字类似。但是 ReentrantLock 更灵活、更强大,增加了轮询、超时、中断、公平锁和非公平锁等高级功能。

2.2 公平锁和非公平锁

  • 公平锁:

        锁被释放之后,先申请的线程先得到锁。性能较差一些,因为公平锁为了保证时间上的绝对顺序,上下文切换更频繁。

  • 非公平锁:

        锁被释放之后,后申请的线程可能会先获获取到锁,是随机或者按照其他优先级排序的。性能更好,但可能会导致某些线程永远无法获取锁。

2.3 synchronized 和 ReentrantLock 

  • 两者都是可重入锁

        可重入锁也叫递归锁,指的是线程可以再次获取自己的内部锁。比如一个线程获得了某个对象的锁,此时这个对象锁还没有释放,当其再次想要获取这个对象的锁的时候还是可以获取的,如果是不可重入锁,就会造成死锁。JDK 提供的所有 Lock 的实现类,包括 synchronized 关键字锁都是可重入的。

        例如,下面代码中,method1() 和method2() 都被 synchronized 关键字修饰,method1() 调用了 method2()。

public class SynchronizedDemo {public synchronized void method1() {System.out.println("方法1");method2();}public synchronized void method2() {System.out.println("方法2");}
}

由于 synchronized 锁是可重入的,同一个线程在调用 method1() 时可以直接获取当前对象的锁,执行 method2() 的时候可以再次获取这个对象的锁,不会产生死锁问题。如果 synchronized 是不可重入锁,由于该对象的锁已被当前线程锁持有且无法释放,这就导致线程在执行 method2() 时获取锁失败,会出现死锁问题。

  • synchronized 依赖于 JVM 而 ReentrantLock 依赖于 API

synchronized 是依赖于 JVM 实现的,ReentrantLock 是 JDK 层面实现的(也就是 API 层面,需要 lock() 和 unlock() 方法配合 try/finally 语句块来完成)。

http://www.lryc.cn/news/617531.html

相关文章:

  • monorepo架构设计方案
  • 小白入门指南:Edge SCDN 轻松上手
  • 【NOI】落谷2025/08/10 SCP-J 模拟测试 第10题 求构成三角形的概率
  • qss基础
  • Godot ------ 平滑拖动02
  • 机器学习第九课之DBSCAN算法
  • 智慧工地:以三大监测技术筑牢安全屏障
  • (Arxiv-2025)Phantom-Data:迈向通用的主体一致性视频生成数据集
  • Qwen 3 架构深度解析:混合推理、MoE创新与开源生态的全面突破
  • 工业智造新引擎:BRAV-7135赋能自动化产线升级
  • 第八篇:交互入门:鼠标拾取物体
  • 可视化+自动化:招聘管理看板软件的核心技术架构解析
  • 网络资源模板--基于Android Studio 实现的手绘板App
  • Docker部署MySQL完整指南:从入门到实践
  • Oracle主从incarnation不一致问题解决
  • 如何网络“钓鱼”,钓鱼鱼饵生成工具CobaltStrike使用
  • 云原生应用的DevOps2(Jenkins渗透场景)
  • 【从零开始java学习|第一篇】java中的名词概念(JDK、JVM、JRE等等)
  • JVM 运行时全景:从类加载到 GC 的底层原理与调优指南
  • 在Mac 上生成GitLab 的SSH 密钥并将其添加到GitLab
  • Empire--安装、使用
  • 【12-激活函数】
  • 类和对象(中上)
  • 腾讯 iOA 测评 | 横向移动检测、病毒查杀、外设管控、部署性能
  • 运维学习Day21——LAMP/LNMP 最佳实践
  • react+vite-plugin-react-router-generator自动化生成路由
  • 论文阅读 arxiv 2024 MemGPT: Towards LLMs as Operating Systems
  • Linux:进程调度
  • linux下部署 dify,并配置本地ollama大模型
  • 关系型数据库:原理、演进与生态全景——从理论基石到云原生的深度巡礼