Consider the following code. In order to prevent IndexOutOfBoundsException
while calling listIterator
, we use a reader lock to retrieve the index based iteartor, and writer lock else where when write operation on stockCodes
.
Take note that, we didn't use any locking mechanism to iterate using listIterator
, as it is from CopyOnWriteArrayList
. Locking is not required as ConcurrentModificationException
shall not be thrown.
// 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();
I was wondering, whether I should have try/finally
block, as I cannot see any chance for exception to arise? If using try/finally
is a must, should I use (A) or (B)?
Is there any need for me?
(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();
}
The lock() method is one of the most important methods of the Lock interface. It is used for acquiring the lock. For thread scheduling purposes, the current thread becomes disabled when the lock is not available. The lock() method is a public method that returns void.
tryLock. boolean tryLock() Acquires the lock only if it is free at the time of invocation. Acquires the lock if it is available and returns immediately with the value true . If the lock is not available then this method will return immediately with the value false .
The Lock API provides tryLock() method. The thread acquires lock only if it's available and not held by any other thread. This reduces blocking time of thread waiting for the lock. A thread that is in “waiting” state to acquire the access to synchronized block can't be interrupted.
The other respondents are right: you should always use try/finally.
Regarding whether (A) or (B) is correct, Sun seems to recommend (B) in the JavaDoc of ReentrantReadWriteLock (search for "finally" to see it). I suppose this is because the lock()
method could throw an exception if it fails: for example, the JavaDoc says it will throw an Error
in the obscure case where the same thread attempts to acquire the lock recursively more than 65535 times.
It's good defensive programming. If your code ever changes so that the body throws an exception for any reason whatsoever (including, for example, OutOfMemoryError), you'll be glad you didn't leave the lock in a stuck state.
I'd personally go for (B) - if the lock() method itself were to throw an exception, it would still be balanced. But in practice I don't think it matters that much.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With