死锁产生的必要条件:
1,互斥使用
即当资源被一个线程使用(占有)时,别的线程不能使用
2,不可抢占
资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
3,请求和保持
即当资源请求者在请求其他的资源的同时保持对原有资源的占用。
4,循环等待
即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路
注意:过多的同步会导致死锁
死锁示例如下:
public class MyRun implements Runnable {
private static Object a = new Object();
private static Object b = new Object();
private boolean flag = true;
public void changeFlag(){
flag = false;
}
@Override
public void run() {
if(flag){
synchronized (a) {
System.out.println(Thread.currentThread().getName()+"锁定了资源a");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (b) {
System.out.println(Thread.currentThread().getName()+"锁定资源b");
}
}
}else{
synchronized (b) {
System.out.println(Thread.currentThread().getName()+"锁定了资源b");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (a) {
System.out.println(Thread.currentThread().getName()+"锁定资源a");
}
}
}
}
}
测试如下:
public class Test {
public static void main(String[] args) throws InterruptedException {
MyRun mra = new MyRun();
new Thread(mra,"线程1").start();
Thread.sleep(10);
mra.changeFlag();
new Thread(mra,"线程2").start();
}
}
在我们的项目中,我们不希望看到死锁的发生,为了避免,以上四个条件,破坏其中任意一个,死锁就结束了