2017-03-22 78 views
1

下面的代碼會導致死鎖:死鎖而睡眠時間不與ReentrantLock的相同

public class IntLock implements Runnable { 
    private static ReentrantLock lock1 = new ReentrantLock(); 
    private static ReentrantLock lock2 = new ReentrantLock(); 
    int lock; 

    public IntLock(int lock) { 
     this.lock = lock; 
    } 

    @Override 
    public void run() { 
     try { 
      if (lock == 1) { 
       lock1.lockInterruptibly(); 
       try { 
        Thread.sleep(1000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       lock2.lockInterruptibly(); 
      } else { 
       lock2.lockInterruptibly(); 
       try { 
        Thread.sleep(2000); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
       lock1.lockInterruptibly(); 
      } 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } finally { 
      if (lock1.isHeldByCurrentThread()) { 
       lock1.unlock(); 
      } 
      if (lock2.isHeldByCurrentThread()) { 
       lock2.unlock(); 
      } 
      System.out.println(Thread.currentThread().getName() + " quit"); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 
     Thread t1 = new Thread(new IntLock(1)); 
     Thread t2 = new Thread(new IntLock(2)); 
     t1.start(); 
     t2.start(); 
     Thread.sleep(1000); 
     t2.interrupt(); 
    } 
} 

,但如果我在run方法改變了睡眠時間一樣,它會正確地退出或會導致死鎖我只是想知道 這兩個代碼之間有什麼區別。

+0

這裏沒有死鎖。死鎖將是線程1持有鎖A並試圖聲明鎖B,而線程2持有鎖B並試圖聲明鎖A,或者通常是這樣的一個循環鏈。而僵局是永久的。你有什麼是臨時鎖。 – EJP

+0

但是程序如何暫停,這是否意味着死鎖?只是困惑。 –

回答

0

由於lockInterruptibly將接收到中斷信號。當您設置2000,主線程先睡一覺然後1000毫秒調用t2.interrupt(),T2仍在運行的Thread.sleep(2000),然後InterruptedException的將漁獲代碼

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

而不是

} catch (InterruptedException e) { 
     e.printStackTrace(); 
    } finally { 
     if (lock1.isHeldByCurrentThread()) { 
      lock1.unlock(); 

所以它不會釋放鎖。

+0

好吧,'最後'是不是意味着它會被執行,無論發生什麼事情? –

+0

當然,它會被執行。 –

+0

那麼爲什麼它不會釋放鎖,我剛剛在'finally'中釋放了鎖定 –