编写一个示例程序,展示如何产生多线程死锁的情况。
在Java中,你可以使用synchronized
关键字和多个线程来创建一个死锁的例子。下面是一个简单的例子,其中有两个资源Resource1
和Resource2
,以及两个线程Thread1
和Thread2
。每个线程都试图首先获取Resource1
,然后获取Resource2
,但是获取的顺序相反,从而导致死锁。
public class DeadlockExample {
// 创建两个资源
private final Object resource1 = new Object();
private final Object resource2 = new Object();
public void thread1Proc() {
synchronized (resource1) {
System.out.println("线程1: 锁定资源 1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource2) {
System.out.println("线程1: 锁定资源 2");
}
}
}
public void thread2Proc() {
synchronized (resource2) {
System.out.println("线程2: 锁定资源 2");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (resource1) {
System.out.println("线程2: 锁定资源 1");
}
}
}
public static void main(String[] args) {
DeadlockExample deadlock = new DeadlockExample();
// 创建线程1
new Thread(() -> {
deadlock.thread1Proc();
}, "线程1").start();
// 创建线程2
new Thread(() -> {
deadlock.thread2Proc();
}, "线程2").start();
}
}
在这个例子中,thread1Proc
方法首先锁定resource1
,然后尝试锁定resource2
。同时,thread2Proc
方法首先锁定resource2
,然后尝试锁定resource1
。由于每个线程都持有另一个线程需要的资源,并且都在等待获取另一个资源,因此它们将永远等待下去,从而导致死锁。
注意:这个例子是为了演示死锁的概念,而在实际编程中应该避免死锁的发生。可以使用一些策略来预防死锁,例如按照固定的顺序获取资源,使用超时机制,或者使用更高级的并发控制工具,如java.util.concurrent
包中的工具。