死锁(Deadlock)是指两个或多个进程在执行过程中因争夺资源而造成的一种互相等待的现象
死锁通常发生在多任务系统中,其中进程通过竞争有限的资源来完成任务
死锁通常涉及互斥、持有和等待三个条件。
死锁的原因
- 互斥条件(Mutual Exclusion): 资源一次只能被一个进程使用,其他进程必须等待
- 占有且等待(Hold and Wait): 进程在请求新的资源时保持对已分配资源的占有
- 不可抢占(No Preemption): 已分配的资源不能被强行抢占,只能在进程主动释放时才能被其他进程获取
- 循环等待(Circular Wait): 进程之间形成一个循环等待资源的关系
如何避免死锁:
- 破坏互斥条件: 允许多个进程同时访问某些资源,如读取文件
- 破坏占有且等待: 进程在执行之前一次性获取所有需要的资源,或者在执行过程中释放已经占有的资源并重新请求
- 破坏不可抢占: 允许操作系统在适当的时候抢占资源
- 破坏循环等待: 引入资源层次结构,强制进程按照顺序请求资源,防止循环等待的发生
实现一个简单的死锁
public class DeadlockExample {
static class Resource {
// 用于演示的两个资源
private final Object resource1 = new Object();
private final Object resource2 = new Object();
public void method1() {
synchronized (resource1) {
System.out.println("Thread " + Thread.currentThread().getId() + " acquired resource1");
// 模拟一些操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println("Thread " + Thread.currentThread().getId() + " acquired resource2");
}
}
}
public void method2() {
synchronized (resource2) {
System.out.println("Thread " + Thread.currentThread().getId() + " acquired resource2");
// 模拟一些操作
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println("Thread " + Thread.currentThread().getId() + " acquired resource1");
}
}
}
}
public static void main(String[] args) {
final Resource resource = new Resource();
Thread thread1 = new Thread(() -> resource.method1());
Thread thread2 = new Thread(() -> resource.method2());
thread1.start();
thread2.start();
// 等待两个线程结束
try {
thread1.join();
thread2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}