Skip to Content
面试题库Juc[面试题] 什么是排他锁和共享锁?

[面试题] 什么是排他锁和共享锁?

📖 版块 A:知识讲解版 (温故知新)

  • 排他锁(Exclusive Lock,简称 X 锁):又称写锁。如果事务 T 对数据 A 加上排他锁,则只允许事务 T 读取和修改 A。在此期间,其他任何事务都不能再对 A 加任何类型的锁,直到事务 T 释放锁。它保证了在修改数据时,不会有其他事务进来干扰。

  • 共享锁(Shared Lock,简称 S 锁):又称读锁。如果事务 T 对数据 A 加上共享锁,则事务 T 可以读取 A 但不能修改 A。其他事务也可以对 A 加共享锁进行读取,但不能加排他锁。这实现了“多读并发”,即多个事务可以同时读,但只要有人在读,谁都不能写。

  • 兼容性矩阵

    • 共享锁 (S) 与 共享锁 (S):兼容(可以同时存在)。
    • 共享锁 (S) 与 排他锁 (X):冲突。
    • 排他锁 (X) 与 排他锁 (X):冲突。

🎤 版块 B:面试实战版 (高手逐字稿)

Q:什么是排他锁和共享锁?

💬 高手逐字稿

简单来说,排他锁和共享锁是并发控制中为了实现“读写分离”而设计的两种基础锁模型。

首先是共享锁,通常也叫 S 锁或读锁。它的核心逻辑是“共享”,允许多个事务或线程同时持有一把锁来读取同一个资源。在 MySQL 里,我们可以通过 LOCK IN SHARE MODE 来显式加锁。它的存在是为了保证在读取期间,数据不会被其他人修改。

然后是排他锁,也叫 X 锁或写锁。它的核心逻辑是“独占”。一旦一个线程对资源加了排他锁,其他任何线程既不能读(加 S 锁),也不能写(加 X 锁)。在 MySQL 中,所有的 DML 操作(如 Update、Delete)都会自动加排他锁,或者我们可以用 FOR UPDATE 显式申请。

在实际应用中,我理解这两者的组合主要是为了解决“读写冲突”。如果全是排他锁,系统就退化成了串行化,并发性能极差;引入共享锁后,就可以实现“读读不互斥”,大幅提升了系统的吞吐量。

这里有一个容易被忽略的边界细节:锁的升级与死锁风险。在很多数据库引擎或复杂的业务逻辑中,如果两个事务同时持有了同一个资源的共享锁(S 锁),然后它们又同时尝试将手中的 S 锁升级为排他锁(X 锁)去进行写操作,这时候就会发生死锁。因为 A 在等 B 释放 S 锁,B 也在等 A 释放 S 锁,谁也升不上去。

所以在高并发的 Java 开发中,如果我们使用 ReentrantReadWriteLock,它是支持锁降级(从写锁降级为读锁)的,但不支持锁升级。这就是为了在设计层面规避这种由于锁竞争导致的死锁问题。我们在业务代码中也会遵循“能用读锁不加写锁”的原则,来最大化系统的并发能力。

最后更新于:
⏱️

登录后开始阅读

当前 MVP 版本只开放邮箱密码登录注册。完成登录后即可进入面试题内容。

还没有账号?先去注册