2013-10-02 6 views
2

누구든지이 코드가 교착 상태로 고통받는 이유를 말해 줄 수 있습니까?다음 코드가 교착 상태에 빠지는 이유는 무엇입니까?

public class BrokenOrderingReentredLock implements Runnable { 

    private Object lock1 = new Object(); 
    private Object lock2 = new Object(); 

    public static void main(String[] args) throws InterruptedException { 
     BrokenOrderingReentredLock runnable = new BrokenOrderingReentredLock(); 
     Thread thread1 = new Thread(runnable, "thread1"); 
     Thread thread2 = new Thread(runnable, "thread2"); 
     thread1.start(); 
     Thread.sleep(500); 
     thread2.start(); 
    } 

    @Override 
    public void run() { 
     try { 
      String threadName = Thread.currentThread().getName(); 
      synchronized (lock1) { 
       System.out.println(threadName + " has lock1"); 
       synchronized (lock2) { 
        System.out.println(threadName + " has lock2"); 
         System.out.println(threadName + " reenters lock1"); 
         lock1.wait(); 
         lock2.wait(); 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } } 
+0

스택 추적을 할 때 무엇이 ​​보입니까? 교착 상태를 보여줘야합니다. –

답변

7

Thread1 시작하고 lock1lock2을 가져옵니다. Thread1은 (lock1.wait())입니다.

Thread2이 시작되고 lock1을 얻은 다음 영원히 lock2을 기다립니다. Thread1은 알림을 받기 위해 대기 중이지만 절대로 전달되지 않습니다.

DEADLOCK!

0

thread1이 lock1을 잠근 다음 lock2를 잠급니다. Thread1은 lock1.wait를 호출하여 lock1에 대한 잠금을 해제하고 누군가가 notify (결코 발생하지 않음)를 호출 할 때까지 thread1을 대기시킵니다.

Thread2가 따라 와서 lock1을 잠급니다. 그런 다음 thread1에 여전히 잠금이 있으므로 lock2에 대한 잠금이 차단됩니다.

lock1.wait와 lock2.wait 사이에 메시지를 넣으면 어느 스레드도 그렇게 멀리 떨어져 있지 않으므로 lock2의 잠금을 해제 할 수 없다는 것을 알 수 있습니다.

관련 문제