在 Java 并发编程中,synchronized
和 Lock
(通常指 ReentrantLock
)是两种不同的线程同步机制,它们在实现方式、功能和性能上有显著区别:
🧱 核心区别总结
特性 |
synchronized |
Lock (ReentrantLock) |
实现级别 |
JVM 原生关键字(字节码指令) |
JDK API 接口(Java 类实现) |
锁释放 |
自动释放(代码块结束/异常) |
必须手动 unlock() (否则死锁) |
锁获取方式 |
阻塞式(不可中断) |
可轮询/定时/中断获取 |
公平性 |
非公平锁(默认) |
可选公平/非公平锁 |
条件变量 |
单一等待队列(wait/notify ) |
支持多个条件队列(Condition ) |
性能 |
优化后接近 Lock(JDK6+) |
高竞争场景下更优 |
锁绑定 |
与对象关联 |
灵活绑定任意资源 |
🔧 详细对比
1. 实现机制
synchronized
- JVM 层面通过
monitorenter
/monitorexit
字节码指令实现
- 锁状态记录在对象头的 Mark Word 中
Lock
- Java API 实现(如
ReentrantLock
基于 AQS 队列)
- 通过 CAS 操作和 volatile 变量管理锁状态
2. 锁获取与释放
操作 |
synchronized |
Lock |
获取锁 |
进入同步块自动获取 |
lock.lock() 手动调用 |
释放锁 |
退出同步块自动释放 |
必须 try-finally 中调用 unlock() |
示例代码 |
synchronized(obj) { ... } |
lock.lock(); try{...} finally{ lock.unlock(); } |
3. 高级功能对比
🔄 锁中断