互斥条件:该资源任意时刻只能被一个线程占用 请求与保持条件:一个线程因请求资源而阻塞,对已经获得的资源保持不放 不剥夺条件:线程已获得的资源在末使用完之前不能被其他线程强行剥夺,只有自己使用完毕后才释放资源。 循环等待条件:若干进程之间形成头尾相接的循环等待资源关系
破坏互斥条件:这个是办不到的,用锁就是为了让他们互斥 破坏请求和保持条件:一次性申请所有资源 破坏不剥夺条件:占用部分资源的线程进一步申请其他资源时,如果申请不到,可以主动释放它占有的资源。 破坏循环等待条件:靠按序申请资源来预防,按某一顺序申请资源,释放资源则反序释放,破坏循环等待条件
运行结果
Thread[线程1,5,main]get resource1 Thread[线程2,5,main]get resource2 Thread[线程1,5,main]waiting get resource2 Thread[线程2,5,main]waiting get resource1线程 A 通过 synchronized (resource1) 获得 resource1 的监视器锁,然后通过Thread.sleep(1000);让线程 A 休眠 1s 为的是让线程 B 得到执行然后获取到 resource2 的监视器锁。线程 A 和线程 B 休眠结束了都开始企图请求获取对方的资源,然后这两个线程就会陷入互相等待的状态,这也就产生了死锁
修改线程2
new Thread(() -> { synchronized (resource1) { System.out.println(Thread.currentThread() + "get resource1"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread() + "waiting get resource2"); synchronized (resource2) { System.out.println(Thread.currentThread() + "get resource2"); } } }, "线程 2").start();运行结果
Thread[线程1,5,main]get resource1 Thread[线程1,5,main]waiting get resource2 Thread[线程1,5,main]get resource2 Thread[线程 2,5,main]get resource1 Thread[线程 2,5,main]waiting get resource2 Thread[线程 2,5,main]get resource2线程 1 首先获得到 resource1 的监视器锁,这时候线程 2 就获取不到了。然后线程 1 再去获取 resource2 的监视器锁,可以获取到。然后线程 1 释放了对 resource1、resource2 的监视器锁的占用,线程 2 获取到就可以执行了。这样就破坏了破坏循环等待条件,因此避免了死锁。