活锁 & 死锁

简介: 活锁 & 死锁

一、活锁(liveLock)

活锁是指线程间资源冲突激烈,引起线程不断的尝试获取资源,不断的失败。活锁有点类似于线程饥饿,虽然资源并没有被别人持有,但由于各种原因而无法得到。最常见的原因是进程组的执行顺序不合理,导致某些先需要的资源被后置。活锁和死锁的不同在于,活锁的状态是变化的,只是无法达到目的。活锁有可能在一定时间后自动解开,但死锁不能。

二、死锁(Deadlock)

死锁是指在一个并发系统中,多个线程或进程因争夺系统资源而造成的相互等待的一种状态。简言之,就是两个或多个进程或线程无限期地阻塞等待对方占有的资源。死锁是一种常见的并发问题,可能会造成系统资源的浪费和性能下降。

举个简单的例子:


假设有两个程序员 A 和 B 同时需要使用打印机来进行打印学习资料。程序员 A 先占用了打印机不释放,程序员 B 先拿到了电子学习资料不释放。此时:


程序员 A 说:你先给我学习资料,我打印完了就给你打印机

程序员 B 说:不行,你先给我打印机,我打印完了就给你学习资料 此时两个程序员A B就陷入了无限期的互相等待,形成了死锁。


在这个例子中,打印机和文件都是一种资源,程序员 A 和程序员 B 相当于两个线程,每个线程需要占用对方所需的资源才能完成操作。

经典死锁问题:哲学家就餐问题

通过上述例子,我们可以归纳出死锁产生的四个必要条件(缺一不可):

  1. 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
  2. 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
  3. 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
  4. 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样 就形成了一个等待环路

当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

其中最容易破坏的就是 “循环等待”,因此我们最常用的一种阻止死锁的的技术就是“锁排序”,这种方式就可以通过破坏循环等待,阻止死锁发生。


比如还是上面的哲学家就餐,如果规定只能先拿标号比较小的筷子,那么死锁问题自然就不会发生了:

相关文章
|
6月前
|
监控 算法 安全
|
3月前
死锁原因
死锁原因
40 1
|
3月前
活锁与死锁
【8月更文挑战第22天】
52 4
|
6月前
|
安全 算法 程序员
|
6月前
|
SQL 存储 设计模式
如何与死锁斗争!!!
尽量不要改动线上数据库的字段,因为会触发锁表影响业务,严重时还可能出现死锁!数据库真的出现了死锁,业务全挂了,这种时候应该怎么办呢?本文就给大家分享一下数据库死锁的排查思路,万一出了问题,也有底气去解决。
62 1
|
6月前
|
安全 Java 测试技术
发生死锁怎么办
发生死锁怎么办
66 0
|
算法 安全
死锁的总结(2)
死锁的总结
47 0
|
算法 调度
死锁的理解
死锁的理解
83 0
|
安全 算法
初识死锁问题
关于对死锁的详解