死锁代表的是一种情形:多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放。由于线程被无限期阻塞,因此程序不可能正常终止(例如:客户一方占用资金等待货物资源,经销商一方占用货物资源等待资金,双方都占用一种资源,并且都在等待一种资源,这就导致交易流程无法正常进行,也就形成了所谓的“死锁”)
当上述的四个条件都满足时,便形成死锁,当然,死锁的情况下如果打破上述任何一个条件,便可以让死锁消失。开发中应该尽量避免死锁
死锁在代码形式上通常需要锁的嵌套,也就是在锁的内部还有锁
package ThreadPool;
//必然死锁案例
public class ThreadDead {
// 定义两个资源对象
public static Object resource1=new Object();
public static Object resource2=new Object();
public static void main(String[] args) {
//定义两个线程
//线程1
new Thread(new Runnable() {
@Override
public void run() {
//上锁,第一次线程1锁住资源1
synchronized (resource1){
System.out.println("线程1占用资源1,请求资源2");
/*
休眠1s,这是为了保证死锁必然发生
以计算机的运行速度,保证了休眠1s的情况下,必然会执行线程2
此时资源1已经被上锁,待线程2开始运行,第一步就会讲资源2上锁
此时两个资源已经都被上锁
待两个线程休眠结束,开始运行
线程1进入锁阻塞状态,因为资源2已经被锁
线程2也进入锁阻塞状态,因为资源1已经被锁
两个线程都进入锁阻塞状态,无法正常结束,形成死锁
*/
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//上锁,第二次线程1锁住资源2
synchronized (resource2){
System.out.println("线程1成功占用资源2");
}
}
}
}).start();
//线程2
new Thread(new Runnable() {
@Override
public void run() {
//上锁
synchronized (resource2){
System.out.println("线程2占用资源2,请求资源1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//上锁
synchronized (resource1){
System.out.println("线程2成功占用资源1");
}
}
}
}).start();
}
}线程1占用资源1,请求资源2
线程2占用资源2,请求资源1程序仍在运行,且永远不会自行停止,这就形成了死锁