Java并发编程:synchronized与Lock的深度对比

前言

synchronized和Lock是Java并发编程中两种最常用的锁机制。面试必问,实战必用。本文深度对比两者的区别,帮你彻底搞懂何时用哪个。

一、基本用法对比

synchronized用法

// 同步方法
public synchronized void method1() {
    // 业务代码
}

// 同步代码块
public void method2() {
    synchronized(this) {
        // 业务代码
    }
}

// 静态方法锁Class对象
public static synchronized void method3() {
    // 业务代码
}

Lock用法

private final Lock lock = new ReentrantLock();

public void method() {
    lock.lock();
    try {
        // 业务代码
    } finally {
        lock.unlock();  // 必须手动释放
    }
}

二、核心区别对比

特性synchronizedLock
获取/释放 自动 手动
响应中断 不支持 支持
超时获取 不支持 支持
公平锁 非公平 可选
条件变量 单条件 多条件
锁状态 不可知 可查询

三、Lock的高级特性

1. 可中断获取

try {
    lock.lockInterruptibly();
} catch (InterruptedException e) {
    // 响应中断
}

2. 超时获取

if (lock.tryLock(3, TimeUnit.SECONDS)) {
    try {
        // 获取锁成功
    } finally {
        lock.unlock();
    }
} else {
    // 获取锁失败
}

3. 公平锁

// 公平锁:按等待顺序获取
Lock fairLock = new ReentrantLock(true);

// 非公平锁:可能插队
Lock unfairLock = new ReentrantLock(false);

4. 多条件变量

private final Lock lock = new ReentrantLock();
private final Condition notFull = lock.newCondition();
private final Condition notEmpty = lock.newCondition();

// 生产者
public void put(Object item) throws InterruptedException {
    lock.lock();
    try {
        while (isFull()) notFull.await();
        // 添加元素
        notEmpty.signal();
    } finally {
        lock.unlock();
    }
}

// 消费者
public Object take() throws InterruptedException {
    lock.lock();
    try {
        while (isEmpty()) notEmpty.await();
        // 取出元素
        notFull.signal();
        return item;
    } finally {
        lock.unlock();
    }
}

四、性能对比

JDK 6之后,synchronized做了大量优化(偏向锁、轻量级锁、重量级锁),性能与Lock差距不大。

  • 低竞争:synchronized性能更好
  • 高竞争:Lock性能略优

五、使用建议

优先使用synchronized:

  • 简单的同步场景
  • 不需要高级特性
  • 代码简洁优先

使用Lock:

  • 需要可中断获取锁
  • 需要超时获取锁
  • 需要公平锁
  • 需要多条件变量

六、常见问题

Q: 为什么Lock要手动释放?

A: 因为Lock不会自动释放,如果忘记unlock会导致死锁。这也是Lock的缺点之一。

Q: synchronized是可重入锁吗?

A: 是的,同一个线程可以多次获取同一把synchronized锁。

总结

synchronized简单易用,Lock功能强大。实际开发中,优先使用synchronized,需要高级特性时再考虑Lock。

本文由AI辅助创作。

posted @ 2026-03-28 19:38  弥烟袅绕  阅读(33)  评论(0)    收藏  举报