Java-死锁

死锁定义:死锁是指两个或两个以上的进程在执行过程当中,因为竞争资源或者因为彼此通讯而形成的一种阻塞现象,若无外力做用,它们都将没法推动下去,此时称系统处于死锁状态或系统产生了死锁,这些永远在相互等待的进程称为死锁进程。ide

例子:哲学家进餐问题函数

死锁产生的必要条件:this

  1. 互斥条件:进程对所分配到的资源不容许其余进程进行访问,若其余进程访问该资源,只能等待,直到占有该资源的进程使用完后释放该资源。
  2. 请求和保持:进程得到必定资源后,能够对其余资源发出获取请求,但同时对本身已经得到的资源保持不放
  3. 不可剥夺条件:进程已经得到的资源,在未完成使用以前,不能够被剥夺,只能在使用完成以后本身释放。
  4. 循环等待:进程发生死锁后,必然存在一个进程-资源之间环形链。

破坏产生死锁的任何一个必要条件均可以消除死锁现象。spa

写一个简单的死锁程序:线程

package com.fpc.Test;
class thread1 implements Runnable {
    private DeadLock deadlock;
    
    //构造函数
    public thread1( DeadLock deadlock ) {
        this.deadlock = deadlock;
    }
    
    @Override
    public void run( ) {
        try {
            deadlock.lock1toLock2();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

class thread2 implements Runnable {
    private DeadLock deadlock;
    
    //构造函数
    public thread2( DeadLock deadlock ) {
        this.deadlock = deadlock;
    }
    
    @Override
    public void run( ) {
        try {
            deadlock.lock2toLock1();
        } catch( Exception e ) {
            e.printStackTrace();
        }
    }
}

public class DeadLock {
    private Object lock1 = new Object();
    private Object lock2 = new Object();
    
    public void lock1toLock2() {
        synchronized( lock1 ) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized( lock2 ) {
                System.out.println("lock1toLock2 end.....");
            }
        }
    }
    
    public void lock2toLock1() {
        synchronized( lock2 ) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            synchronized( lock1 ) {
                System.out.println("lock2toLock1 end.....");
            }
        }
    }
    
    public static void main( String[] args ) {
        DeadLock d = new DeadLock();
        thread1 t1 = new thread1(d);
        thread2 t2 = new thread2(d);
        Thread th1 = new Thread(t1);
        Thread th2 = new Thread(t2);
        th1.start();
        th2.start();
    }
}

怎么去分析死锁:设计

先用jps命令查看虚机中运行的Java线程的pid:3d

而后根据pid 去查看 jstack pid:code

避免死锁的方式对象

1.设计时考虑清楚锁的顺序,尽可能减小嵌套的加锁交互数量blog

2.死锁产生的缘由是资源的循环等待,那么给获取锁加个时间限制,超过必定的时间尚未获取到对象的锁,那么就释放已经获取的对象的锁。固然synchronized是没法作到的,能够用可重入锁ReentrantLock

 

针对上面的程序能够这么改:

public void lock1toLock2() throws InterruptedException {
        if (lock1.tryLock(3000, TimeUnit.MILLISECONDS)){
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            try {
                if ( lock2.tryLock(3000, TimeUnit.MICROSECONDS) ) {
                    System.out.println("lock1toLock2 end.....");
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
      }
    }

运行再次查看jps:能够看到没有出现DeadLock线程了,嗯,不会出现死锁了

相关文章
相关标签/搜索