1.什么是死锁
多个进程或者线程相互等待对方的资源,在未得到对方资源之前,都不会释放自己的资源,就造成了相互等待的现象。
java代码示例:
public class Main {
/**
* 资源1
*/
private static final Object OBJ_1 = new Object();
/**
* 资源2
*/
private static final Object OBJ_2 = new Object();
/**
* 死锁演示
*/
private static void deadLock() {
//线程1
Thread t1 = new Thread(() -> {
//获取资源1
synchronized (OBJ_1) {
System.out.println(Thread.currentThread().getName() + "获取资源1");
//睡眠2秒,保证在线程2拿到资源2
sleep(2000);
//获取资源2
synchronized (OBJ_2) {
System.out.println(Thread.currentThread().getName() + "获取资源2");
}
}
});
//线程2
Thread t2 = new Thread(() -> {
//获取资源2
synchronized (OBJ_2) {
System.out.println(Thread.currentThread().getName() + "获取资源2");
//睡眠2秒,保证在线程1拿到资源1
sleep(2000);
//获取资源1
synchronized (OBJ_1) {
System.out.println(Thread.currentThread().getName() + "获取资源1");
}
}
});
//启动两个线程
t1.start();
t2.start();
}
/**
* 睡眠
*
* @param millis
*/
private static void sleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/**
* 主函数
* @param args
*/
public static void main(String[] args) {
deadLock();
}
}
2.死锁的四个必要条件
条件1:资源的互斥性,一个资源同一时刻只能被一个进程或线程占有
条件2:请求与保持,一个进程或线程在申请新资源的同时保持对原有资源的占有
条件3:不可剥夺,资源申请者不能从资源占有者手中夺取资源,只能由占有者自由释放。
条件4:循环等待,多个进程或线程相互等待对方已占有的资源。
3.如何预防死锁
避免死锁的方法就是破坏它成立的条件。 只要破坏必要条件中的一个,即可避免死锁的产生。
- 首先,资源的互斥性是必须要保持的,互斥性是非共享资源的特性。非共享资源就是进程或线程需要去抢占的资源。
2.我们只能从其他三个条件入手。
破坏条件2:当一个进程或线程在请求资源的时候,它需要释放已占有的资源。
破坏条件3:当一个进程或线程在一定时间内无法请求到资源的时候,需要释放自身所占有的资源。
破坏条件4:规范进程或线程请求资源的顺序,按照相同顺序请求资源,避免循环等待。
4避免死锁的方法
1.一次性锁定所有需要的资源
2.所有进程或线程按照相同顺序加锁
3.银行家算法
网友评论