死锁 - 这个程序死锁了吗?

时间:2016-09-12 14:48:09

标签: java multithreading

此代码中是否可能发生死锁?

我多次运行它并没有一个,但是任务要求解释是否可能出现死锁情况。

public class DeadlockTest {
  public static void main(String[] args) {
    ReentrantLock[] locks = new ReentrantLock[3]; 
    for (int i = 0; i < 3; i++) {
        locks[i] = new ReentrantLock(); 
    }
    WorkerThread[] threads = new WorkerThread[3]; 
    for (int i = 0; i < 3; i++) {
        threads[i] = new WorkerThread(locks[i], locks[(i+1)%3]);
        threads[i].start();
    }
  }
}

class WorkerThread extends Thread {
   private ReentrantLock l1;
   private ReentrantLock l2;
      public WorkerThread(ReentrantLock l1, ReentrantLock l2) {
         this.l1 = l1;
         this.l2 = l2; 
      }
   public void run() {
     l1.lock();
     l2.lock();
     System.out.println("Working now.");
     l1.unlock();
     l2.unlock();
   } 
}

2 个答案:

答案 0 :(得分:3)

这里肯定存在死锁的可能性:

  • 线程0将按此顺序尝试按住锁0和1;
  • 线程1将按此顺序尝试按住锁1和2;
  • 线程2将按此顺序尝试按住锁定2和0。

回想一下,即使在代码中您调度线程“一个接一个地”运行,底层调度程序也可以选择其他方式。此外,这不是因为当前执行了一个线程,而是执行了所有的代码。

这种情况是可能的:

  • 线程1持有锁1;
  • 线程2持有锁2;
  • 线程1尝试并保持锁定2:它不能 - >线程被阻止;
  • 线程0持有锁0;
  • 线程2尝试并保持锁0:它不能 - &gt;线程被阻止;
  • 线程0尝试并保持锁1:它不能 - &gt;线程被阻止。

死锁!

答案 1 :(得分:0)

fge为您的问题提供了一个清晰的答案。但你仍然可能会认为为什么它在运行时不会陷入僵局。

尝试添加

   try
    {
      Thread.sleep(10);
    }
    catch (InterruptedException e)
    {
      e.printStackTrace();
    }

在l1.lock();

之后

你会意识到如何能够陷入僵局。