Javadoc和一些答案(Threads - Why a Lock has to be followed by try and finally)指出:java的嘗試終於解開成語
在大多數情況下,下面的語句,應使用:
Lock l = ...;
l.lock();
try {
// access the resource protected by this lock
} finally {
l.unlock();
}
我看到這個成語在標準Java的例子庫。 這是我使用它的例子。 acc1和acc2字段是銀行賬戶的一個衆所周知的例子。主要制約因素是ACC的值的總和 - 它應該是0
public class Main {
int acc1;
int acc2;
ReadWriteLock lock = new ReentrantReadWriteLock();
public int readSum() {
lock.readLock().lock();
try {
return acc1 + acc2;
} finally {
lock.readLock().unlock();
}
}
public void transfer() {
lock.writeLock().lock();
try {
acc1--; // constraint is corrupted
// exception throwed here
acc2++; // constraint is regained
} finally {
lock.writeLock().unlock();
}
}
}
我瞭解使用成語在讀的情況下:如果例外read方法其他線程拋出仍然可以讀/寫一致的資源。但是,如果在寫入方法中讀取的excteption讀取方法可能會讀取不一致的資源。
爲什麼讀取不一致的值比無限鎖等待更可取? 爲什麼Java庫作者更喜歡這種行爲?
鎖提供某些形式的事務行爲(例如數據的一致視圖)。但是,它們不提供回滾功能。你需要自己實現或使用數據庫。 – jtahlborn
當您的軟件運行一個商業網站,每天交易價值數百萬美元的業務時,如果您的客戶因永久懸掛而導致I/O錯誤,您的客戶將不會感到滿意。 (不要問我怎麼知道!) –
PS:@ GhostCat的答案是關於羅伯特(「叔叔鮑勃」)馬丁所說的_分離問題_---的想法,如果你讓一團代碼負責解決兩個問題或更多不同的問題(例如,鎖定和錯誤處理),將來當需求改變時,它將變成維護噩夢。看看鮑勃叔叔的書:https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882/ –