try-with-resources是另一種選擇(除了Andy的回答),但Lock
不是AutoCloseable
。
所以你可以寫一個包裝器,如解釋here in another SO question和here那麼你可以使用try-with-resource與這個包裝器。
如果您不打算在您的應用程序的多個位置使用類似的構造,它可能不值得您付出努力。
編輯:詳細回答解決Sotirios Delimanolis的問題。
在我看來,OP想拋出一個RuntimeException
如果鎖不能被獲取,並且弄不清finally
塊鎖關閉,因爲如果鎖尚未通過線程保持它可能會引發IllegalMonitorStateException
。
使用Lock
爲您提供了靈活性,以unlock
那個程序員想要的任何地方(而不是在一定try塊的末尾或者在方法結束)&靈活性在關鍵字失蹤,但作爲每個操作的代碼片段,看起來他會立即解鎖try
區塊,因此AutoCloseable
有意義。
下面的代碼地址這兩個問題,
包裝類
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class CloseableReentrantLock extends ReentrantLock implements
AutoCloseable {
private static final long serialVersionUID = 1L;
public CloseableReentrantLock timedLock() throws InterruptedException{
if(this.tryLock(120, TimeUnit.SECONDS))
return this;
else
throw new RuntimeException("timeout");
}
@Override
public void close() throws Exception {
this.unlock();
}
}
客戶
try(CloseableReentrantLock lock = new CloseableReentrantLock().timedLock()) { //do stuff here
}
鎖定收購方案:不hing特別發生,close
方法在try-with-resource塊被調用並且鎖定被解鎖。這是或多或少的方式塊的工作,但你不能用等待時間的選擇,但finally
代碼搞亂&機會,程序員會錯過代碼unlock
& finally
不存在與syncronized
等與Closeable
的情況下包裝。
鎖無法獲得:在這種情況下,因爲資源沒有成功地與嘗試,與資源和試穿與資源本身拋出異常收購,close
不會叫上這個資源所以IllegalMonitorStateException
不會在那裏。 請參閱this question and accepted answer瞭解更多關於嘗試與資源本身的例外。
此示例代碼示出了它進一步,
public class TryResource implements AutoCloseable{
public TryResource getResource(boolean isException) throws Exception{
if (isException) throw new Exception("Exception from closeable getResource method");
else return this;
}
public void doSomething() throws Exception {
System.out.println("In doSomething method");
}
@Override
public void close() throws Exception {
System.out.println("In close method");
throw new Exception("Exception from closeable close method");
}
}
和客戶端,
public class TryResourceClient {
public static void main(String[] args) throws Exception {
try (TryResource resource = new TryResource().getResource(true)){
resource.doSomething();
}
}
}
哇。我現在感到很傻:) – mzzzzb