阿杰,我给你整理一份 Locksynchronized 的区别详解,包含概念、用法、特点对比和适用场景。


一、概念

特性synchronizedLock(java.util.concurrent.locks.Lock)
类型内置锁(JVM 层面)显示锁(Java 类库提供)
用法通过关键字修饰方法或代码块创建 Lock 对象,调用 lock() / unlock()
机制JVM 自动加锁、解锁手动加锁、解锁,需显式调用 unlock()

二、基本用法

1. synchronized

修饰方法

public synchronized void add() {
    // 临界区
    count++;
}

修饰代码块

public void add() {
    synchronized(this) {
        count++;
    }
}


2. Lock

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

Lock lock = new ReentrantLock();

public void add() {
    lock.lock();   // 上锁
    try {
        count++;
    } finally {
        lock.unlock(); // 解锁
    }
}

注意:Lock 必须在 finally 块中释放锁,否则可能发生死锁。


三、主要区别

维度synchronizedLock
是否可中断不可中断可中断(lockInterruptibly)
超时获取锁不支持支持 tryLock(long time, TimeUnit unit)
公平性不支持支持公平锁(ReentrantLock(boolean fair))
释放锁JVM 自动释放必须手动释放 unlock()
性能Java 1.6+ 已优化,可适应轻量级锁高并发场景下性能优于 synchronized
条件变量wait()/notify()/notifyAll()支持多个 Condition,灵活等待/通知
适用场景简单同步复杂同步、可中断、超时等待、多个条件队列

四、适用场景对比

场景推荐使用
简单同步方法或代码块synchronized
高并发场景ReentrantLock
需要公平锁Lock
需要超时获取锁Lock(tryLock)
需要中断等待Lock(lockInterruptibly)
多条件等待Lock + Condition

五、注意事项

  1. synchronized:不用手动释放锁,JVM 自动处理;容易避免死锁,但灵活性差。
  2. Lock:必须在 finally 中释放锁,否则可能死锁;适合复杂业务场景。
  3. 性能
    • Java 1.6+,synchronized 已优化为轻量级锁和偏向锁
    • Lock 在高并发、频繁加锁/解锁场景性能略优

六、总结

  • synchronized:简单、安全,适合方法或代码块的同步。
  • Lock:灵活、高级,用于复杂业务场景,需要手动释放锁、支持中断、超时和多条件。
  • 选择原则
    • 业务简单 → synchronized
    • 高并发或复杂同步 → Lock