死锁必要条件,产生原因,避免,预防,解决

什么是死锁?

死锁是多个线程之间因为抢夺不可剥夺资源而造成相互等待的现象。

举个栗子

现有两个字符串obj1,obj2,还有两个锁线程Lock1和Lock2。Lock1先锁住obj1,再锁住obj2,Lock2先锁住obj2,再锁住obj1。启动两个线程Lock1和Lock2,当某一时刻,Lock1锁住了obj1,请求obj2的资源,而同一时刻Lock2锁住了obj2,请求obj1,此时线程Lock1和Lock2就进入了死锁的状态,因为两个线程进入了相互等待的状态,Lock1等待Lock2所持有的obj2,Lock2等待Lock1所持有的obj1。

代码如下:

public class DeadLock {
    public static String obj1 = "obj1";
    public static String obj2 = "obj2";
    public static void main(String[] args){
        Thread a = new Thread(new Lock1());
        Thread b = new Thread(new Lock2());
        a.start();
        b.start();
    }    
}
class Lock1 implements Runnable{
    @Override
    public void run(){
        try{
            System.out.println("Lock1 running");
            while(true){
                synchronized(DeadLock.obj1){
                    System.out.println("Lock1 lock obj1");
                    Thread.sleep(3000);//获取obj1后先等一会儿,让Lock2有足够的时间锁住obj2
                    synchronized(DeadLock.obj2){
                        System.out.println("Lock1 lock obj2");
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
class Lock2 implements Runnable{
    @Override
    public void run(){
        try{
            System.out.println("Lock2 running");
            while(true){
                synchronized(DeadLock.obj2){
                    System.out.println("Lock2 lock obj2");
                    Thread.sleep(3000);
                    synchronized(DeadLock.obj1){
                        System.out.println("Lock2 lock obj1");
                    }
                }
            }
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}

死锁的产生的原因

1.系统资源不足

系统中不可剥夺的资源数量不能满足多个进程运行的需要,使进程在运行过程中因争夺资源而进入僵局。

2.进程推进顺序不合理

如进程P1和P2分别拥有资源R1和R2,P2要申请R1,P1要申请R2。

死锁产生的四个必要条件

1.互斥

一个资源只能被一个进程使用

2.不可剥夺

一个资源被一个进程使用,在该进程使用的时候,该资源不可被剥夺,只有该进程释放后才能被其他资源使用。

3.请求与保持

进程已经拥有至少一个资源,同时他又请求另一个资源,而这个资源被其他进程占用了,此时请求进程被阻塞,该进程手持已经拥有的资源不放手。

4.循环等待

若干进程之间形成首位相接形成循环等待资源的关系。

例如进行A 等待进程B的资源,进程B等待进程C的资源,进程C等待进程A的资源。

预防死锁(破坏四个必要条件)

1.破坏请求与保持:将资源一次性分配

2.破坏不可剥夺:当进程请求资源被阻塞时,进程释放资源

3.破坏环路等待:将资源从小到大编号,进程按编号递增顺序请求资源

4.破坏互斥:一般来说互斥条件是不能破坏的所以破坏前三条即可

避免死锁

银行家算法,在进程分配资源时先计算这个分配是否安全,如果不安全就不分配,安全就分配。

1.设置加锁顺序:

2.设置加锁时限:在进成功获取锁的时候,添加一个获取锁的时限,如果超过了,就放弃获取锁

3.死锁检测:使用Jconsole

解除死锁

剥夺资源:从其他进程中剥夺一定数量的资源给死锁进程。

撤销进程:撤销代价最小的进程或死锁进程,直到有足够的资源可用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值