首页 > 解决方案 > 用一个简单的例子理解死锁

问题描述

我正在努力理解死锁的基础知识,所以我想出了下面的代码。我有两个线程以相反的顺序获取锁,但它们没有死锁。当我运行它时,我会看到所有的打印输出。我究竟做错了什么?

public class DeadlockBasics {
  private Lock lockA = new ReentrantLock();
  private Lock lockB = new ReentrantLock();

  public static void main(String[] args) {
    DeadlockBasics dk = new DeadlockBasics();
    dk.execute();
  }

  private void execute() {
    new Thread(this::processThis).start();
    new Thread(this::processThat).start();
  }

  // called by thread 1
  public void processThis() {
    lockA.lock();
    // process resource A
    System.out.println("resource A -Thread1");

    lockB.lock();
    // process resource B
    System.out.println("resource B -Thread1");

    lockA.unlock();
    lockB.unlock();
  }

  // called by thread 2
  public void processThat() {
    lockB.lock();
    // process resource B
    System.out.println("resource B -Thread2");

    lockA.lock();
    // process resource A
    System.out.println("resource A -Thread2");

    lockA.unlock();
    lockB.unlock();
  }
}

标签: javamultithreadingdeadlockreentrantlock

解决方案


首先,没有保证哪个线程首先启动。要获得死锁,一个线程必须锁定lockA,然后第二个线程必须锁定,lockB反之亦然。

public void processThis() {
    lockA.lock();
    // here the control should be switched to another thread
    System.out.println("resource A -Thread1");

    lockB.lock();
    ...

但是可能没有足够的时间在线程之间切换,因为您只有几行代码。它太快了。为了模拟一些长时间的工作,在两种方法的第二个锁定之前添加延迟

lockA.lock();
Thread.sleep(200);  // 200 milis

然后第二个线程将能够lockB在第一个释放之前锁定它们


推荐阅读