面试题答案
一键面试死锁产生的根本原因
- 资源竞争:多个线程同时竞争有限的共享资源,且这些资源在同一时刻只能被一个线程占用。
- 资源分配顺序不当:线程获取资源的顺序不合理,形成了循环等待的局面。比如线程A持有资源R1并等待资源R2,线程B持有资源R2并等待资源R1,这种循环等待导致死锁。
活锁产生的根本原因
- 线程间相互响应:线程之间为了响应对方的某种操作,不断改变自己的状态,但始终无法取得进展。例如两个线程都试图给对方让路,不断地相互避让,却没有一个线程能够真正前进。
- 缺乏协调机制:线程之间缺乏有效的协调,在面对一些冲突场景时,无法做出正确决策,从而陷入无效的循环操作。
预防和检测机制及优缺点
1. 资源分配图算法(如银行家算法)
- 预防原理:通过模拟资源分配过程,判断系统是否处于安全状态。在每次资源请求时,检查如果满足该请求后系统是否仍能保持安全状态,如果是则分配资源,否则拒绝请求。
- 优点:能够有效预防死锁,理论上可以避免系统进入死锁状态。
- 缺点:实现复杂,需要系统提前知道所有线程对资源的最大需求,对资源和线程的管理要求较高,实际应用中可能难以满足这些前提条件。
2. 破坏死锁的四个必要条件
- 破坏互斥条件:
- 预防原理:尽量使用可共享的资源替代独占资源。例如将某些独占设备通过虚拟技术转化为可共享设备。
- 优点:从根本上消除死锁产生的可能性,简单直接。
- 缺点:并非所有资源都能实现共享,对于一些必须独占的资源此方法不适用。
- 破坏占有并等待条件:
- 预防原理:要求线程一次性申请所有需要的资源,而不是逐步申请。在申请到所有资源之前,线程不占有任何资源。
- 优点:实现相对简单,能够有效预防死锁。
- 缺点:可能导致资源浪费,因为线程可能会申请一些暂时用不到的资源,降低了资源利用率。而且可能使线程长时间等待,影响系统并发性能。
- 破坏不可剥夺条件:
- 预防原理:当一个线程占有了部分资源并请求其他资源而得不到满足时,系统可以剥夺该线程已占有的资源分配给其他线程。
- 优点:在一定程度上解决死锁问题,适用于对资源及时性要求不高的场景。
- 缺点:实现较为复杂,需要设计合理的资源剥夺策略,否则可能导致数据不一致等问题,并且对线程运行的连续性有影响。
- 破坏循环等待条件:
- 预防原理:对资源进行排序,规定线程只能按照递增(或递减)的顺序申请资源。例如资源R1、R2、R3,线程只能先申请R1,再申请R2,最后申请R3。
- 优点:实现简单,不需要额外复杂的算法,能有效预防死锁。
- 缺点:资源排序可能不合理,某些线程可能因为资源顺序问题需要等待不必要的资源,降低系统并发性能,而且对资源添加或删除时需要重新排序。
3. 死锁检测与恢复机制
- 检测原理:定期检测系统中是否存在死锁。例如通过构建资源分配图,利用深度优先搜索等算法检测图中是否存在环,若存在环则表示可能发生死锁。
- 恢复原理:当检测到死锁后,选择一个或多个线程进行回滚,释放它们占有的资源,使系统从死锁状态中恢复。
- 优点:不需要对线程和资源的访问做过多限制,系统并发性能相对较高,且实现相对简单。
- 缺点:检测和恢复过程需要额外的开销,回滚线程可能导致之前的工作白费,影响系统性能,而且可能无法及时检测到死锁,导致死锁长时间存在影响系统运行。
4. 超时机制
- 预防原理:为线程获取资源设置一个超时时间。如果线程在规定时间内未能获取到所需资源,则放弃当前资源请求,并释放已占有的部分资源(如果有),过一段时间后重新尝试。
- 优点:实现简单,能够有效避免线程因长时间等待资源而陷入死锁或活锁,对系统的侵入性较小。
- 缺点:难以确定合适的超时时间。如果超时时间设置过短,可能导致线程频繁重试,增加系统开销;如果设置过长,可能无法及时避免死锁或活锁。而且可能存在误判,线程在超时时间内其实是在正常执行操作,却被强制中断。