找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

420

积分

0

好友

56

主题
发表于 昨天 01:27 | 查看: 4| 回复: 0

在Java并发编程中,synchronizedReentrantLock的选择与对比是一个高频话题。本文将用生动的比喻为你解析它们的核心区别,帮助你从容应对面试,并在实战中做出正确选择。

synchronized vs ReentrantLock:一场武侠世界的锁之争

身世来历:嫡传弟子 vs 宗门高手

SynchronizedReentrantLock,就好比武林中的两位顶尖高手,但他们的出身完全不同。

Synchronized,我们称之为 “少林锁僧” 。他是Java这门“武林”的嫡传弟子,从1995年Java诞生起,就是这门语言的内功心法之一。他的武功招式直接刻在Java的“武学典籍”(JVM规范)里。

ReentrantLock,我们称之为 “华山剑客” 。他不是语言本身的招式,而是后来加入的门派高手。他来自Java 5时代成立的“并发宗门”(java.util.concurrent包)。这个宗门专门研究多线程、高并发这些现代武学难题。

根本区别:“少林锁僧”的武功是天生的,内置于语言层面;“华山剑客”的武功是后天修炼的,位于API层面。

练功方式:自动流转 vs 手动操控

“少林锁僧”synchronized,修炼的是“自动流转功”。 其用法特别简单,例如:

public synchronized void 取经() {
    // 一次只让一个线程进入
    翻阅秘籍();
}

或者:

public void 取经() {
    synchronized(藏经阁大门) {
        // 锁住大门,别人进不来
        翻阅秘籍();
    }
    // 自动解锁,下个人可以进
}

最大的特点是:锁自动获取,自动释放。 你进入同步代码块,门自动锁上;你出来,门自动打开。即使抛出异常,锁也会被自动释放,避免了死锁风险。

“华山剑客”ReentrantLock,修炼的是“手动操控诀”。 其使用方式如下:

private final ReentrantLock 思过崖大门 = new ReentrantLock();

public void 面壁() {
    思过崖大门.lock();  // 手动锁门
    try {
        面壁思过();
    } finally {
        思过崖大门.unlock();  // 必须手动开门
    }
}

关键区别在于必须显式调用 unlock() “华山剑客”的规矩是:无论临界区内执行成功与否,在 finally 块中必须亲手解锁。如果遗忘,将导致死锁。

武功招式:朴实无华 vs 丰富多彩

“少林锁僧”synchronized,招式朴实,但基本功扎实。 核心特性就两点:

  1. 可重入:同一个线程可重复获取同一把锁。
  2. 互斥:同一时间只允许一个线程进入。

对于大多数并发场景,这已经足够。但“华山剑客”ReentrantLock来自专攻高并发的“并发宗门”,其招式则丰富得多:

第一式:试探敲门手(tryLock

if (思过崖大门.tryLock()) { // 尝试获取,失败立即返回
    try {
        进去练功();
    } finally {
        思过崖大门.unlock();
    }
} else {
    去别处转转(); // 不傻等
}

更有带时限的试探

// 只等待3秒,超时则放弃
if (思过崖大门.tryLock(3, TimeUnit.SECONDS)) {
    // ...
}

第二式:知难而退功(可中断锁) 使用 lockInterruptibly() 方法,等待锁的线程可以被其他线程中断,避免无限期等待。

try {
    思过崖大门.lockInterruptibly(); // 可以被打断的等待
    // ...
} catch (InterruptedException e) {
    // 被中断,处理其他事务
}

第三式:公平对决令(公平锁) “少林锁僧”的锁默认是非公平的(竞争机制,性能高)。而“华山剑客”提供了公平性的选择:

// 公平锁:严格按照线程等待顺序获取锁
ReentrantLock 公平大门 = new ReentrantLock(true);
// 非公平锁:默认模式,谁抢到谁进
ReentrantLock 非公平大门 = new ReentrantLock();

第四式:多重等待室(多个Condition) 这是ReentrantLock招牌绝技synchronized只关联一个隐式的等待队列(wait/notifyAll);而ReentrantLock可以创建多个Condition对象,实现更精细的线程通信。

Lock lock = new ReentrantLock();
Condition 等上房 = lock.newCondition(); // 等待豪华房队列
Condition 等通铺 = lock.newCondition(); // 等待普通床位队列

// 掌柜可以精准通知特定队列
上房空出来了();
等上房.signal(); // 只唤醒一个等待上房的线程
// 或
通铺空出来了();
等通铺.signalAll(); // 唤醒所有等待通铺的线程

实战选型:没有最强,只有最合适

优先选择“少林锁僧”synchronized的场景:

  1. 同步逻辑简单直接。
  2. 不需要尝试获取、定时获取或可中断获取锁等高级功能。
  3. 不想操心锁的释放管理(依赖于自动释放)。
  4. 团队技术栈统一,维护简单。
// 简单的计数器 - synchronized足够简洁安全
public class Counter {
    private int count;
    public synchronized void increment() {
        count++;
    }
}

考虑选择“华山剑客”ReentrantLock的场景:

  1. 需要尝试获取锁(tryLock),避免死锁或长时间等待。
  2. 需要可中断的锁获取机制。
  3. 需要公平锁保证顺序。
  4. 需要复杂的线程间协调(多个Condition)。
  5. 需要实现类似“手递手”的精细锁控制逻辑。

例如,在银行转账这种容易死锁的场景,tryLock就非常有用:

public class BankTransfer {
    private Map<String, ReentrantLock> accountLocks = new HashMap<>();

    public boolean transfer(String from, String to, int amount) {
        // 尝试获取第一把锁
        if (accountLocks.get(from).tryLock()) {
            try {
                // 尝试获取第二把锁
                if (accountLocks.get(to).tryLock()) {
                    try {
                        // 执行转账
                        return true;
                    } finally {
                        accountLocks.get(to).unlock();
                    }
                }
            } finally {
                accountLocks.get(from).unlock();
            }
        }
        return false; // 获取锁失败,可重试或回退
    }
}

关于性能的“江湖传说”

这是一个常见的误解。在Java 6之前synchronized作为重量级锁性能确实较差。但Java 6及之后,JVM团队对synchronized进行了重大优化,引入了锁升级机制

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

这意味着,在低竞争情况下,synchronized的性能开销非常小。只有在高竞争场景下,它才会膨胀为重量级锁。因此,在绝大多数应用场景中,两者的性能差异并不明显,不应作为选型的首要依据。

江湖铁律

记住这条核心原则:能用synchronized解决的,就优先使用synchronized。只有当synchronized的功能无法满足需求时,才考虑使用功能更强大但也更复杂的ReentrantLock

一个恰当的比喻是:synchronized如同自动挡汽车,易于驾驶,安全性高;ReentrantLock如同手动挡汽车,控制精细,性能潜力大,但需要更谨慎的操作,否则易“熄火”(死锁)。深入理解Java并发工具箱中的这些核心组件,是构建健壮高并发应用的基础。




上一篇:S7-200 SMART Modbus TCP客户端实战配置:V2.4版本通信与避坑指南
下一篇:恶意 Chrome 扩展伪装诺顿安全搜索:395个样本代码混淆与C2通信分析
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-8 07:56 , Processed in 0.095467 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表