synchronized 的原理(简单版)

synchronized 是 Java 提供的一种 内置锁(互斥锁) ,主要用来保证 多线程访问共享资源时的互斥性和可见性 。它的底层实现依赖 对象头中的 Mark Word 和 Monitor 机制

首先,每个 Java 对象在内存里都有一个 对象头(Object Header) ,其中有一部分叫 Mark Word ,里面会记录锁的信息,比如锁状态、线程 ID 等。当线程进入 synchronized 代码块时,JVM 会尝试修改对象头中的 Mark Word 来获取锁。

在实现上,synchronized 是基于 Monitor(管程)机制 的。每个对象都可以关联一个 Monitor,当线程进入同步代码块时,相当于获取这个对象的 Monitor;如果获取不到,就会进入等待队列,等锁释放后再竞争。

为了提高性能,JVM 对 synchronized 做了 锁优化和锁升级。锁状态一般会经历:

无锁 → 偏向锁 → 轻量级锁 → 重量级锁。

  • 偏向锁:适用于只有一个线程反复进入同步块的场景,不需要每次都竞争锁。
  • 轻量级锁 :当多个线程交替执行时,通过 CAS + 自旋 来尝试获取锁,避免线程阻塞。
  • 重量级锁:如果竞争比较激烈,锁就会升级为重量级锁,线程会被挂起,由操作系统负责调度。

当线程退出 synchronized 代码块时,就会释放锁,并唤醒等待队列中的线程重新竞争锁。

总结来说:

synchronized 的底层核心是 对象头 + Monitor + CAS + 锁升级机制,通过这些机制在保证线程安全的同时尽量减少线程阻塞,提高并发性能。

synchronized 和 ReentrantLock 的区别是什么?

synchronizedReentrantLock 都是 Java 中实现线程同步的 可重入锁,都可以保证多线程访问共享资源时的线程安全,但它们在实现方式和功能上有一些区别。

第一,实现层面不同
synchronizedJava 关键字 ,属于 JVM 层面的锁,底层是通过 对象头的 Mark Word 和 Monitor 机制 实现的。
ReentrantLockJDK 提供的类 ,实现基于 AQS(AbstractQueuedSynchronizer)框架 ,通过 CAS + FIFO 队列 来实现线程的阻塞和唤醒。

第二,获取锁的方式不同
synchronized 在进入同步块时 自动加锁 ,退出同步块时 自动释放锁
ReentrantLock 需要开发者 手动调用 lock()unlock() ,通常需要在 finally 中释放锁,否则可能导致死锁。

第三,功能灵活性不同
ReentrantLock 功能更丰富,例如:

  • 可以实现 公平锁和非公平锁
  • 支持 tryLock() 尝试获取锁
  • 支持 可中断锁 lockInterruptibly()
  • 可以通过 Condition 实现多个等待队列

synchronized 的功能相对简单,只能是 非公平锁,也不能响应中断。

第四,性能方面

在早期 JDK 版本中,ReentrantLock 的性能通常优于 synchronized

但在 JDK1.6 之后synchronized 引入了 偏向锁、轻量级锁、自旋锁等优化机制 ,性能已经和 ReentrantLock 差距不大,在很多场景甚至更好。

最后总结一句:

synchronized 使用简单、由 JVM 自动管理;
ReentrantLock 更灵活、功能更丰富,适合复杂的并发控制场景。

面试最后可以补一句加分总结:

一般情况下 优先使用 synchronized ,代码更简单;

如果需要 公平锁、可中断锁或 tryLock 等高级功能 ,才会选择 ReentrantLock

==========================更精简======================================

synchronized 是 Java 提供的 内置互斥锁 ,用于保证多线程访问共享资源时的 线程安全和可见性 。它的底层主要依赖 对象头中的 Mark Word 和 Monitor 机制实现。

每个 Java 对象都有 对象头(Object Header) ,其中的 Mark Word 会记录锁状态、线程 ID 等信息。当线程进入 synchronized 代码块时,JVM 会尝试修改 Mark Word 来获取锁;如果获取失败,线程就会进入 Monitor 的等待队列,等锁释放后再竞争。

为了提高性能,JVM 对 synchronized 做了 锁优化和锁升级,锁状态一般会经历:

无锁 → 偏向锁 → 轻量级锁 → 重量级锁

偏向锁适用于 单线程重复加锁 ;轻量级锁通过 CAS + 自旋 减少线程阻塞;如果竞争激烈,就会升级为 重量级锁,线程会被挂起,由操作系统调度。

所以总结来说:
synchronized 的核心原理是 对象头 + Monitor + CAS + 锁升级机制

相关推荐
peijiping14 小时前
Agent 工具执行:并行(parallel_tool_calls)和后台(run_in_background)到底有什么区别? (学习笔记)
笔记·学习·ai agent·claude code
Oll Correct14 小时前
Adobe illustrator 案例四:吃豆人 (Pac-Man)图标绘制
笔记·ui·adobe·illustrator
LuminousCPP14 小时前
单链表专题(四)-刷题复盘篇-LeetCode 138 随机链表复制|原地拷贝法突破复杂指针操作
数据结构·笔记·算法·leetcode·链表
萌新小白YXY14 小时前
SAE J1587/SAE J1708 协议笔记
笔记·单片机·嵌入式硬件
IT古董15 小时前
【MES学习笔记系列】MES 推荐书籍与资源
笔记·学习
一米阳光866115 小时前
软考(中级)软件设计师核心笔记(9)算法——时间复杂度与空间复杂度、查找算法、排序算法
笔记·算法·职场发展·软考·软件设计师·中级职称
米饭不加菜15 小时前
常用基本求导公式与法则(超详细推导版——上)
经验分享·笔记
青山是哪个青山1 天前
LangChain 学习笔记(四):Message 与提示词模板
笔记·学习·langchain
Shell运维手记1 天前
Linux 常用基础命令学习笔记
linux·运维·笔记·学习·算法·github
FakeOccupational1 天前
【电路笔记 STM32】Cortex-M7 内核上的数据缓存(D-Cache)结构+MPU+DMA&Cache+STM32CubeMX配置
笔记·stm32·缓存