一、基础回答
1. 用过吗?用来做什么?
用过。synchronized 是 Java 内置的悲观锁 关键字,用来解决多线程并发安全问题,保证同一时刻只有一个线程执行被锁定的代码,避免线程安全问题(如原子性、可见性、有序性问题)。
它有 3 种使用方式:
- 修饰实例方法:锁当前实例对象
- 修饰静态方法:锁当前类的 Class 对象
- 修饰代码块:锁括号里指定的对象
2. 核心原理(极简版) - 基于对象头 + Monitor(监视器锁)实现
- 每个 Java 对象都自带一个 Monitor 锁
- 线程进入同步代码时:尝试获取锁 → 获取成功执行,获取不到就阻塞等待
- 执行完毕 / 异常时:自动释放锁
- 特性:可重入、不可中断、非公平锁
二、进阶原理(加分项,面试官最爱)
1. 对象头结构(锁存在哪里)
Java 对象在内存分 3 部分:
对象头 + 实例数据 + 对齐填充
- 对象头里存锁信息:
- Mark Word:存储哈希码、分代年龄、锁状态、持有锁线程 ID
- Klass Pointer:指向类元数据指针
synchronized 的锁状态,就存在 Mark Word 里。
2. Monitor 工作机制(核心原理)
每个对象关联一个 Monitor(C++ 实现的 ObjectMonitor),内部结构:
_owner:持有锁的线程
_EntryList:锁等待队列
_WaitSet:wait () 等待队列
执行流程:
(1)线程进入同步块 → 尝试把 _owner 设为自己
(2)成功:持有锁,执行代码
(3)失败:进入 _EntryList 阻塞(BLOCKED)
(4)锁释放:_owner 置空,唤醒队列线程竞争锁
3. JDK 1.6 锁升级(重要)
JDK1.6 对 synchronized 做了锁优化,锁会逐级升级,不可逆:
无锁 → 偏向锁 → 轻量级锁 → 重量级锁
- 偏向锁
只有一个线程用锁,无 CAS 竞争
记录线程 ID 到对象头,下次直接进 - 轻量级锁(自旋锁)
两个线程交替执行,CAS 竞争
不阻塞,自旋等待,减少内核态切换 - 重量级锁
多线程激烈竞争
线程阻塞,依赖操作系统互斥量(Mutex Lock)
4. 关键特性
- 可重入:同一线程再次获取锁不会死锁(底层计数器实现)
- 不可中断:锁等待中不能被中断
- 非公平:新线程可能直接抢到锁,不排队
三、面试满分背诵模板
面试官:synchronized 用过吗?原理是什么?
用过,synchronized 是 Java 内置的悲观锁,用来保证多线程下的原子性、可见性、有序性,解决并发安全问题。
它可以修饰实例方法、静态方法、同步代码块,分别锁实例对象、Class 对象、自定义对象。
原理层面:
它基于对象头 Mark Word + Monitor 监视器锁实现,每个 Java 对象都自带一把锁。
线程执行时会尝试获取 Monitor,成功则执行,失败进入阻塞队列。
JDK1.6 做了锁优化,会按 无锁→偏向锁→轻量级锁→重量级锁 自动升级,提升性能。
特性是可重入、不可中断、非公平锁。
总结
基础:解决并发安全,3 种用法,基于对象 + Monitor
核心:对象头 Mark Word 存锁状态
高分:锁升级流程(偏向→轻量→重量)
特性:可重入、非公平、不可中断