并发代码-死锁
死锁原因
两个或多个线程互相持有对方所需要的资源,导致这些线程处于等待状态,都等待对方释放资源,如果都不主动释放,产生死锁。
互斥:资源具有排它性,只能被一个进程占用,直到被该进程释放
请求和保持条件:一个进程请求其他资源发生阻塞时,已获得的资源保持不放。
不剥夺条件:资源在没被进程释放前,其他进程无法对他剥夺占用
循环等待条件:等待的进程形成一个环路(死循环),造成永久阻塞。
死锁代码
public class DeadLock {
private static Object locka = new Object();
private static Object lockb = new Object();
public void deadLock(){
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (locka){ // 获取A锁
System.out.println(Thread.currentThread().getName() + "get locka");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("need lockb"); // 获取B锁
synchronized (lockb){
System.out.println(Thread.currentThread().getName() + "get lockb");
}
}
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lockb){ // 获取B锁
System.out.println(Thread.currentThread().getName() + "get lockb");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("need locka");
synchronized(locka){ // 获取A锁
System.out.println(Thread.currentThread().getName() + "get locka");
}
}
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
new DeadLock().deadLock();
}
}
避免死锁
产生死锁的四个必要条件:互斥条件、持有并等待条件、不可剥夺条件、环路等待条件。避免死锁问题就只需要破环其中一个条件就可以
加锁顺序 所有的线程,按照相同的顺序获得锁
加锁时限 尝试获取锁的时候加一个超时时间,一个线程没有在给定时限内成功获取锁,进行回退、释放所有已经获得的锁,然后等待一段随机的时间再重试。
死锁检测 当一个线程请求锁失败时,这个线程可以遍历锁的关系图看看是否有死锁发生。
一个可行的做法:释放所有锁,回退,并且等待一段随机的时间后重试
一个更好的方案:线程设置优先级,让一个(或几个)线程回退。
最常见的并且可行的就是使用资源有序分配法,来破环环路等待条件。
线程 A 和 线程 B 获取资源的顺序要一样,当线程 A 是先尝试获取资源 A,然后尝试获取资源 B 的时候,线程 B 同样也是先尝试获取资源 A,然后尝试获取资源 B。线程 A 和 线程 B 总是以相同的顺序申请自己想要的资源。
操作系统-银行家算法
保证系统动态分配资源后,不会进入不安全状态,避免可能产生的死锁。
当进程提出资源请求,资源能够满足该请求,判断满足请求后系统状态是否安全
- 如果安全,给该进程分配资源
- 否则不分配资源,申请资源的进程将阻塞。
鸵鸟策略
解决死锁的 代价很高,不采取任何措施,能获得更高的性能。
死锁发生 概率很低,就算发生死锁对对用户的影响并不大,所以可以采用鸵鸟策略。
大多数操作系统,Linux、Unix、Windows,解决死锁的办法是忽略它。
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库