死锁

什么是死锁?

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

举个例子:比如线程在获得了锁A并且没有释放的情况下去申请锁B,这时,另一个线程已经获得了锁B.在释放锁B之前又要先获得锁A.因此闭环发生,陷入死锁循环。

死锁产生的必要条件

  • 互斥条件;进程在某一时间内独占资源
  • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
  • 不剥夺条件:进程已获得资源,在未使用完之前不强行剥夺
  • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系

这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁

死锁的预防

理解了死锁的原因,尤其是产生死锁的四个必要条件,就可以最大可能地避免、预防和解除死锁。所以,在系统设计、进程调度等方面注意如何不让这四个必要条件成立,如何确定资源的合理分配算法,避免进程永久占据系统资源。此外,也要防止进程在处于等待状态的情况下占用资源。因此,对资源的分配要给予合理的规划。

区分死锁、活锁、饥饿

所谓活锁:任务或者执行者没有被阻塞, 由于某些条件没有满足 , 导致一直重复尝试 ,失败, 尝试 , 失败。
活锁和死锁的区别在于,处于活锁的实体是在不断的改变状态,所谓的“活”,而处于死锁的实体表现为等待;活锁有可能自行解开,死锁则不能。

饥饿:一个或多个线程因为种种原因无法获得所需要的资源,导致一直在无法执行。
java中导致饥饿的原因:

  1. 高优先级线程吞噬所有的低优先级线程的cpu时间
  2. 线程被永久堵塞在一个等待进入同步块的状态,因为其他线程总是能在它之前持续的对该同步块进行访问。
  3. 线程在等待一个本身也处于永久等待完成的对象(比如调用这个对象的wait()方法),因为其他线程总是被持续的唤醒。

JAVA中如何确保N个线程可以访问N个资源,但同时又不导致死锁?

死锁发生的四个必要条件是:资源互斥、请求与保持条件,不剥夺条件,循环等待条件,避免死锁最常用的方法就是指定线程获取锁的顺序,这样可以避免循环等待的发生。

一个死锁Demo

class Pen {
    private String pen = "笔" ;
    public String getPen() {
        return pen;
    }
}
class Book {
    private String book = "本" ;
    public String getBook() {
        return book;
    }
}
class DeadLock {
    private static Pen pen = new Pen() ;
    private static Book book = new Book() ;
    public static void main(String[] args) {
        new DeadLock().deadLock();
    }
    public void deadLock() {
        Thread thread1 = new Thread(new Runnable() { // 笔线程
            @Override
            public void run() {
                synchronized (pen) {
                    System.out.println(Thread.currentThread()+" :我有笔,我就不给你");
                    synchronized (book) {
                        System.out.println(Thread.currentThread()+" :把你的本给我!");
                    }
                }
            }
        },"Pen") ;
        Thread thread2 = new Thread(new Runnable() { // 本子线程
            @Override
            public void run() {
                synchronized (book) {
                    System.out.println(Thread.currentThread()+" :我有本子,我就不给你!");
                    synchronized (pen) {
                        System.out.println(Thread.currentThread()+" :把你的笔给我!");
                    }
                }
            }
        },"Book") ;
        thread1.start();
        thread2.start();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值