我们如何使用最后尝试Lock.lock和Lock.unlock

时间:2011-01-12 02:03:00

标签: java

请考虑以下代码。为了在调用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();
}

2 个答案:

答案 0 :(得分:11)

其他受访者是对的:您应该始终使用try / finally。

关于(A)或(B)是否正确,Sun似乎在JavaDoc of ReentrantReadWriteLock中推荐(B)(搜索“finally”以查看它)。我想这是因为lock()方法如果失败就会抛出异常:例如,JavaDoc说它会在一个模糊的情况下抛出Error,同一个线程试图以递归的方式获取锁定超过65535次。

答案 1 :(得分:6)

这是一个很好的防守编程。如果您的代码发生变化,以至于身体因任何原因(包括OutOfMemoryError)抛出异常,您会很高兴您没有将锁定置于卡住状态。

我个人会去(B) - 如果lock()方法本身要抛出一个异常,它仍然是平衡的。但在实践中,我认为这并不重要。