JAVA死锁

面试中经常会被问到死锁,今天就来整理一下死锁的相关知识。

首先看一下死锁的产生,死锁产生的情况有很多种,例如进程推进顺序不当产生死锁、PV操作使用不当产生死锁、资源分配不当引起死锁、对临时性资源使用不加限制引起死锁等。

那么,到底什么是死锁?死锁是指2个及2个以上的进程在执行过程中,由于竞争资源或由于彼此通信而造成的一种阻塞现象,若无外力作用,它们都无法推进下去,这些永远在互相等待的进程称为死锁进程。

死锁不仅与系统拥有的资源数量有关,而且与资源分配策略,进程对资源的使用要求以及并发进程的推进顺序有关,如果面试中面试官让写一个死锁的案例,最简单的方式就是在同步代码块中嵌套另外一个同步代码块,两个同步代码块使用2个不同的锁。例如:

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();
        }
    }
}

例子中Lock1先锁obj1,Lock2先锁obj2,Lock1再去锁obj2,但是obj2已经被Lock2锁住了,因此锁住失败,同理Lock2也没法锁住obj1,死锁就发生了。

系统形成死锁有4个必要条件:

*互斥条件(mutual exclusion):系统中存在临界资源,进程应互斥地使用这些资源

*占有和等待条件(hold and wait):进程请求资源得不到满足而等待时,不释放已占有的资源

*不剥夺条件(no preemption):已被占用的资源只能由属主释放,不允许被其它进程剥夺

*循环等待条件(circular wait):存在循环等待链,其中,每个进程都在链中等待下一个进程所持有的资源,造成这组进程永远等待

要防止死锁,只需要破坏4个必要条件之一即可满足。破坏第一个条件,使资源可同时访问而不是互斥使用,但许多资源如可写文件、磁带机等具有天生的互斥性,不能被同时访问,因此有的场合不可行。破坏第二个条件,静态分配,让进程在执行中不再申请资源,就不会出现占有某些资源再等待另一些资源的情况,但会严重降低资源利用率。破坏第三个条件,采用剥夺式调度方法,当进程在申请资源未获准许的情况下,如主动释放资源,再去等待。比较好的方法是采用层次分配策略(破坏条件2和条件4),把资源分成多个层次,当进程得到某一层的一个资源后,只能再申请较高层次的资源。当进程是释放某层的一个资源时,必须先释放占有的较高层次的资源,当进程得到某一层的一个资源后,它想申请该层的另一个资源时,必须先释放该层中的已占资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值