一个简单的死锁代码#

public class DeadLock{
    static Object o1 = new Object();
    static Object o2 = new Object();

    public static void main(String[] args) {
        new Thread(new Runnable() {
            public void run() {
                synchronized (o1) {
                    System.out.println("线程1锁o1");
                    try {
                        Thread.sleep(1000);//让当前线程睡眠,保证让另一线程得到o2,防止这个线程启动一下连续获得o1和o2两个对象的锁。
                        synchronized (o2) {
                            System.out.println("线程1锁o2");
                        }
                    } catch (InterruptedException e) {                  
                        e.printStackTrace();
                    }
                }
            }
        }).start();

        new Thread(new Runnable() {
            public void run() {
                synchronized (o2) {
                    System.out.println("线程2锁o2");
                    synchronized (o1) {
                        System.out.println("线程2锁o1");
                    }
                }
            }
        }).start();
    }
}

 

什么是死锁
死锁,是指多个线程在运行过程中因争夺资源而造成的一种僵局,若无外力作用,它们都将无法再向前推进。

死锁的4个必要条件
互斥条件:一个资源每次只能被一个线程使用;
请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放;
不剥夺条件:进程已经获得的资源,在未使用完之前,不能强行剥夺;
循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。

如何避免(预防)死锁
破坏“请求和保持”条件:让进程在申请资源时,一次性申请所有需要用到的资源,不要一次一次来申请,当申请的资源有一些没空,那就让线程等待。不过这个方法比较浪费资源,进程可能经常处于饥饿状态。还有一种方法是,要求进程在申请资源前,要释放自己拥有的资源。

破坏“不可抢占”条件:允许进程进行抢占,方法一:如果去抢资源,被拒绝,就释放自己的资源。方法二:操作系统允许抢,只要你优先级大,可以抢到。

破坏“循环等待”条件:将系统中的所有资源统一编号,进程可在任何时刻提出资源申请,但所有申请必须按照资源的编号顺序提出(指定获取锁的顺序,顺序加锁)。

posted @ 2020-07-23 11:45  chenxibobo  阅读(551)  评论(0编辑  收藏  举报