Java多线程死锁示例及其解释

Java Q&A Hub 使用 GPT-4o-mini 回答

问题:

Java面试题之多线程 实现一个死锁?

回答:

在Java中,死锁是指两个或多个线程在执行过程中,因为争夺资源而造成的一种互相等待的状态。为了实现一个简单的死锁示例,我们可以创建两个线程,每个线程都持有一个锁并试图获取另一个线程持有的锁。以下是一个简单的示例代码:

public class DeadlockExample {

    // 创建两个锁
    private static final Object lock1 = new Object();
    private static final Object lock2 = new Object();

    public static void main(String[] args) {
        // 创建第一个线程
        Thread thread1 = new Thread(() -> {
            synchronized (lock1) {
                System.out.println("Thread 1: Holding lock 1...");
                // 暂停一段时间以确保线程2能够获得lock2
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                System.out.println("Thread 1: Waiting for lock 2...");
                synchronized (lock2) {
                    System.out.println("Thread 1: Acquired lock 2!");
                }
            }
        });

        // 创建第二个线程
        Thread thread2 = new Thread(() -> {
            synchronized (lock2) {
                System.out.println("Thread 2: Holding lock 2...");
                // 暂停一段时间以确保线程1能够获得lock1
                try { Thread.sleep(100); } catch (InterruptedException e) {}
                System.out.println("Thread 2: Waiting for lock 1...");
                synchronized (lock1) {
                    System.out.println("Thread 2: Acquired lock 1!");
                }
            }
        });

        // 启动线程
        thread1.start();
        thread2.start();
    }
}

代码解释:

  1. 锁的创建:我们创建了两个对象 lock1lock2,它们将作为锁使用。
  2. 线程1:在获取 lock1 后,线程1 休眠一段时间,然后尝试获取 lock2
  3. 线程2:在获取 lock2 后,线程2 也休眠一段时间,然后尝试获取 lock1
  4. 死锁发生:由于线程1持有 lock1 并等待 lock2,而线程2持有 lock2 并等待 lock1,这就导致了死锁。

注意事项:

  • 运行这个程序时,可能会看到输出,但最终会导致程序挂起,因为两个线程互相等待对方释放锁。
  • 在实际开发中,应尽量避免死锁的发生,可以通过合理的锁顺序、使用定时锁等方式来避免死锁。