2011-08-05 17 views
6

一個鎖總是跟着一個try/finally塊,爲什麼?主題 - 爲什麼一個鎖必須緊跟着嘗試,最後是

ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
Lock read = readWriteLockBitmap.readLock(); 
Lock write = readWriteLockBitmap.writeLock(); 
int shared = 0; 

public void function1(){ 
    read.lock(); 
    try{ 
     //reading shared int 
    } 
    finally{ 
     read.unlock(); 
    } 
} 

public void function 2(){ 
    write.lock(); 
    try{ 
     //modify shared int 
    } 
    finally{ 
     write.unlock(); 
    } 
} 

爲什麼有這個try/finally塊,而不是簡單地編寫代碼如下:

ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
Lock read = readWriteLockBitmap.readLock(); 
Lock write = readWriteLockBitmap.writeLock(); 
int shared = 0; 

public void function1(){ 
    read.lock(); 
    //reading shared int 
    read.unlock(); 
} 

public void function 2(){ 
    write.lock(); 
    //modify shared int 
    write.unlock(); 
} 
+0

可能重複的[我們將如何最後使用try.lock.lock和lock.unlock](http:// stackoverflow。com/questions/4664717/how-will-we-use-try-finally-for-lock-lock-and-lock-unlock) – JasonMArcher

回答

6

萬一有什麼差錯,你要確保鎖(引發異常等)無論發佈什麼。這只是標準的做法,儘管在這種情況下技術上可能是不必要的。

2

要確保無論發生什麼情況,即使拋出異常,在離開方法之前,仍然會解鎖鎖定的流。

3

問題不在於你需要try塊。關鍵是要確保如果你的應用程序拋出瞭解鎖仍然被調用的任何類型的異常。否則,鎖將保持鎖定狀態。

10

因爲try/finally塊是保證一段代碼在另一段代碼完成後才執行的唯一方法。

你問爲什麼不這樣做:

public void function1(){ 
    read.lock(); 
    this.getSharedInt(); 
    read.unlock(); 
} 

this.getSharedInt()拋出一個異常,會發生什麼?那麼你的read.unlock()行不會被執行,導致程序死鎖。當然,它可能被100%認證,現在不會拋出異常,但是當你重構將共享int存儲在文件或數據庫中時會發生什麼?

最後,不要忘記,try/finally還會計算錯誤,即使函數保證不會拋出任何異常,運行時可以在程序的幾乎任何行處拋出錯誤。

請注意,此代碼也可以工作,但它會吞噬異常。如果使用finally,則允許異常正常傳播,但仍可在所有情況下解鎖。

public void function2(){ 
    read.lock(); 
    try { 
     this.getSharedInt(); 
    } catch(Throwable t) {} 
    read.unlock(); 
} 
+1

+1爲重構位 –

4

所以這樣的事情不會發生:

private static ReentrantReadWriteLock readWriteLockBitmap = new ReentrantReadWriteLock(); 
private static Lock read = readWriteLockBitmap.readLock(); 
private static Lock write = readWriteLockBitmap.writeLock(); 
private static int shared = 0; 

public static void function1() { 
    read.lock(); 
    somethingThatMightThrowAnException(); 
    read.unlock(); 
} 

private static void somethingThatMightThrowAnException() { 
    throw new RuntimeException("I'm a bad man."); 
} 

public static void function2() { 
    write.lock(); 
    //modify shared int 
    write.unlock(); 
} 

public static void main(String[] args) { 
    try { 
     function1(); 
    } catch (Exception e) { 
     System.out.println("Got an exception, but so what?"); 
    } 
    function2(); 
} 
+1

+1爲「我是個壞人」。 :d – jdmichal

0

http://www.google.co.uk/#sclient=psy&hl=en&q=java+Why+a+Lock+has+to+be+followed+by+try+and+finally+%3F

首先命中是:http://download.oracle.com/javase/1,5.0/docs/api/java/util/concurrent/locks/Lock.html

引用的關鍵部分:

在在大多數情況下,下面的語句,應使用:

Lock l = ...; 
l.lock(); 
try { 
    // access the resource protected by this lock 
} finally { 
    l.unlock(); 
} 

當鎖定和解鎖發生在不同的範圍,必須 注意保證,同時持有鎖 所執行的所有代碼被試,終於還是儘量保護 - 確保在必要時鎖定爲 。

相關問題