安卓白话文面试(3) —— 并发与锁?厕所的使用权争夺战

8 阅读5分钟

职场里最让人崩溃的场景是什么?不是加班,而是早上抢厕所
你想想:一间厕所,三个急得不行的同事,谁先上?怎么排队?万一有人锁门不出来?
今天咱们就把多线程并发,聊成一场厕所争夺战。


1. 为什么需要锁?——因为资源有限

公司里只有一间厕所(共享资源),张三、李四、王五三个人(多个线程)都想用。
如果不加规则,三个人同时冲进去……那画面太美不敢看。
所以厕所门上的就派上了用场:谁抢到锁,谁进去,其他人乖乖排队

对应到安卓里,多个线程同时操作同一个变量或文件,不加锁就会数据错乱——好比三个人同时记账,你写+1,他写-1,最后账对不上。
synchronized 就是公司统一装的自动感应门锁:你进去自动锁上,出来自动打开,不用操心。而且现在JVM和ART对它做了锁升级(平时很轻快,只有争抢激烈时才变重),性能并不差。


2. 锁的公平与非公平——排队能插队吗?

有的公司厕所门口自觉排队(公平锁),先来的人先进。
有的公司靠抢,谁跑得快谁先进(非公平锁)。非公平锁效率高,但可能导致有人等很久“饿死”。

Java 里的 ReentrantLock 让你自己选:new ReentrantLock(true) 公平排队,false(默认)非公平抢着进。
可重入锁又是什么?意思是:你已经占着厕所了,突然想起来忘了拿手机,还能再进去一次——同一个线程可以多次获得同一把锁,不会死锁。

⚠️ 但ReentrantLock密码锁,必须手动unlock()。如果你忘了在finally里关锁,异常时门就永远锁死。而synchronized自动门锁会在异常时自动释放,更安全。


3. 死锁——你等我,我等你,大家一起憋着

最恐怖的情况:
张三进了厕所A,手里还攥着厕所B的钥匙;李四进了厕所B,手里攥着厕所A的钥匙。
两人都在等对方出来,谁也不放手——这就是死锁

怎么避免?按顺序拿钥匙:比如给厕所编号,只能按1→2的顺序申请。或者加超时:等太久就主动放弃,释放自己的锁。


4. 锁的粒度——别把整栋楼都锁了

有人上厕所,顺手把整层楼的厕所全锁上——这就是粗粒度锁,性能极差。
聪明的做法:只锁自己用的那间
对应到代码,synchronized 可以锁整个方法(粗),也可以只锁几行核心代码(细)。锁的粒度越小,并发越高


5. 厕所门口的“有人/无人”牌子——volatile的作用

有时候你并不需要锁门,只需要知道厕所是否被占用这个状态(一个boolean变量)。
如果A线程把牌子翻到“有人”,B线程却看不到(可见性问题),就会直接拉门闯进去。
这时用volatile修饰这个标志:保证一个线程改了,其他线程立刻能看见。它比锁轻量得多,专门解决可见性,不解决原子性。


6. 等待与唤醒——厕所里的“稍等”牌子

张三蹲在里面,突然发现没纸了,他不能直接出来,但也不想一直锁着门。
他可以wait:主动释放锁,在厕所里喊“我先让出来,你们谁帮我拿包纸,拿到再叫我”。
外面李四拿到纸后notify:“纸来了,你继续”。
这就是Object.wait/notify机制,用于线程间的协作,而不是单纯的互斥。


总结表格

概念生活比喻技术实现
共享资源公司唯一的厕所多线程访问的变量/文件
互斥机制(内置锁)自动感应门锁(synchronized)JVM自动管理,异常释放
互斥机制(显式锁)密码锁(ReentrantLock)手动lock/unlock,需finally
公平锁排队上厕所先到先得,开销大
非公平锁冲进去抢效率高,可能线程饿死
可重入锁拿手机再进去同一线程可多次获得锁
死锁你等我、我等你互相持有对方需要的锁
锁粒度锁一间 vs 锁一层楼细粒度提高并发
可见性厕所门口的状态牌volatile(轻量通知)
等待/通知蹲坑喊人帮忙wait/notify(线程协作)

面试官爱怎么问?

:什么是死锁?怎么避免?
:就像两个人互相等对方出厕所,结果谁都出不来。避免方法:按固定顺序拿锁,或者用tryLock(timeout)设置超时放弃。

:synchronized 和 ReentrantLock 有什么区别?
:synchronized是自动门锁(异常自动释放,JVM有锁升级优化);ReentrantLock是密码锁(功能多:公平、可中断、可超时),但必须手动在finally里解锁,否则会永久死锁。

:volatile 能替代 synchronized 吗?
:不能。volatile只保证你看到“有人/无人”的牌子(可见性),但不保证三个人同时翻牌子时的原子操作。好比牌子从“无人”变“有人”这个过程如果被两个线程同时做,还是会乱。


人话总结

并发就是多人抢资源,锁就是厕所门闩——没锁天下大乱,锁不好可能集体憋死。而volatile只是门口的提示牌,别拿它当锁用。

汇总导航

安卓白话文面试导航