死锁

本文详细探讨了死锁的概念,包括定义、产生原因(资源竞争、进程推进顺序非法)、必要条件(互斥、不剥夺、请求和保持、循环等待)以及经典示例。此外,介绍了死锁的预防策略(破坏必要条件)和避免方法(如有序资源分配法、银行家算法),以及检测和解除死锁的策略。最后,提到了在Java程序中如何通过jstack命令检测死锁问题。
摘要由CSDN通过智能技术生成

死锁的定义

   两个或两个以上的进程在执行过程中,因争夺共享资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去。

死锁产生的原因

1)系统资源的竞争
   通常系统中拥有的不可剥夺资源,其数量不足以满足多个进程运行的需要,使得进程在运行过程中,会因争夺资源而陷入僵局,如磁带机、打印机等。只有对不可剥夺资源的竞争 才可能产生死锁,对可剥夺资源的竞争是不会引起死锁的。

2)进程推进顺序非法
   进程在运行过程中,请求和释放资源的顺序不当,也同样会导致死锁。例如,并发进程 P1、P2分别保持了资源R1、R2,而进程P1申请资源R2,进程P2申请资源R1时,两者都会因为所需资源被占用而阻塞。
   信号量使用不当也会造成死锁。进程间彼此相互等待对方发来的消息,结果也会使得这些进程间无法继续向前推进。例如,进程A等待进程B发的消息,进程B又在等待进程A 发的消息,可以看出进程A和B不是因为竞争同一资源,而是在等待对方的资源导致死锁。

除了以上两种情况,还存在线程自己将自己锁住。如果一个线程先后两次调用lock且不是可重入锁,在第二次调用的时候由于锁已经被占用,那么线程就会被挂起等待线程会挂起等待占用锁的线程释放锁。然而锁正是被自己占用着的,该线程又被挂起而没有机会释放锁,因此就永远处于挂起等待状态了,于是就形成了死锁。

死锁产生的必要条件

  1. 互斥条件:在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待
  2. 不剥夺条件:进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走
  3. 请求和保持条件:进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放
  4. 循环等待条件:存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被链中下一个进程所请求

产生死锁的一个例子

/** 
* 一个简单的死锁类 
* 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒 
* 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒 
* td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定; 
* td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定; 
* td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。 
*/  
public class DeadLock implements Runnable {
     
    public int flag = 1;  
    //静态对象是类的所有对象共享的  
    private static Object o1 = new Object(), o2 = new Object();  
    @Override  
    public void run() {
     
        System.out.println("flag=" + flag);  
        if (flag == 1) {
     
            synchronized (o1) {
     
                try {
     
         
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值