请考虑以下代码。为了在调用IndexOutOfBoundsException
时阻止listIterator
,我们使用读取器锁定来检索基于索引的iteartor,并在写入操作stockCodes
时使用写入锁定。
请注意,我们没有使用任何锁定机制来使用listIterator
进行迭代,因为它来自CopyOnWriteArrayList
。不需要锁定,因为不会抛出ConcurrentModificationException
。
// stockCodesReaderLock is reader lock from java.util.concurrent.locks.ReadWriteLock
// stockCodes is CopyOnWriteArrayList
// Acquire iterator in a safe way.
stockCodesReaderLock.lock();
final int stockCodesSize = stockCodes.size();
if (currIndex < stockCodesSize) {
listIterator = stockCodes.listIterator(currIndex);
}
stockCodesReaderLock.unlock();
我想知道,我是否应该try/finally
阻止,因为我看不出有任何异常出现的机会?如果必须使用try/finally
,我应该使用(A)还是(B)?
我有什么需要吗?
(A)
try {
stockCodesReaderLock.lock();
final int stockCodesSize = stockCodes.size();
if (currIndex < stockCodesSize) {
listIterator = stockCodes.listIterator(currIndex);
}
} finally {
stockCodesReaderLock.unlock();
}
(B)
stockCodesReaderLock.lock();
try {
final int stockCodesSize = stockCodes.size();
if (currIndex < stockCodesSize) {
listIterator = stockCodes.listIterator(currIndex);
}
} finally {
stockCodesReaderLock.unlock();
}
答案 0 :(得分:11)
其他受访者是对的:您应该始终使用try / finally。
关于(A)或(B)是否正确,Sun似乎在JavaDoc of ReentrantReadWriteLock中推荐(B)(搜索“finally”以查看它)。我想这是因为lock()
方法如果失败就会抛出异常:例如,JavaDoc说它会在一个模糊的情况下抛出Error
,同一个线程试图以递归的方式获取锁定超过65535次。
答案 1 :(得分:6)
这是一个很好的防守编程。如果您的代码发生变化,以至于身体因任何原因(包括OutOfMemoryError)抛出异常,您会很高兴您没有将锁定置于卡住状态。
我个人会去(B) - 如果lock()方法本身要抛出一个异常,它仍然是平衡的。但在实践中,我认为这并不重要。