我正在实现我的RunnableFuture
版本,并且在run()
方法结束时需要原子化状态更改。状态字段的具体列表无关紧要。Runnable
可以异常完成,也可以正常完成。因此,它可以访问try
块的尾部,也可以不访问。我还可以访问catch
块,然后访问finally
块。
所有这3个位置都应该被原子化地更改,但我看不到"interblock"锁定结构。因此,我使用getHoldCount()
来决定是否调用lock()
:
public void run() {
Runnable runnable;
lock.lock();
try{
runnable = this.runnable;
done = false;
running = true;
result = null;
}
finally {
lock.unlock();
}
try {
if( !cancel ) {
runnable.run();
}
if( lock.getHoldCount()==0 ) lock.lock();
exception = null;
result = finalResult;
}
catch (Exception e) {
if( lock.getHoldCount()==0 ) lock.lock();
exception = e;
result = null;
}
finally {
if( lock.getHoldCount()==0 ) lock.lock();
done = true;
running = false;
lock.unlock();
}
}
这是正确的吗?有更好的方法吗?
为什么不链接try-finally
语句:
try {
lock.lock();
// Do something ...
} finally {
try {
// Do more ...
} finally {
try {
// Do more ...
} finally {
lock.unlock();
}
}
每当逻辑变得足够复杂,以至于我不得不问"这能工作吗?"我将其分解为子例程:
public void run() {
setup();
exception ex = doRun();
report(ex);
}
private void setup() {
lock.lock();
try{
done = false;
running = true;
result = null;
} finally {
lock.unlock();
}
}
private Exception doRun() {
try {
if( !cancel ) {
this.runnable.run();
}
} catch (Exception e) {
return e;
}
return null;
}
private void report(Exception ex) {
lock.lock();
try {
done = true;
running = false;
if (ex != null) {
exception = ex;
result = null;
} else {
exception = null;
result = finalResult;
}
} finally {
lock.unlock();
}
}