2011-01-12 4 views
5

次のコードを考えてみましょう。 listIteratorを呼び出している間にIndexOutOfBoundsExceptionを呼び出さないようにするには、リーダロックを使用してiteartorに基づくインデックスを取得し、ライターロック以外では、stockCodesに書き込み操作を行います。Lock.lockとLock.unlockを試してみましょう

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

[スレッド - なぜロックを試して最後に実行しなければならないのですか?](http://stackoverflow.com/questions/6950078/threads-why-a-lock-has-to-be-followed- by-try-and-finally) – Raedwald

答えて

11

他の回答者は正しいです:常にを試してみてください。

(A)または(B)が正しいかどうかについては、JavaDoc of ReentrantReadWriteLock(B)を推奨しています。これは、lock()メソッドが失敗した場合に例外をスローする可能性があるためです。例えば、JavaDocは、同じスレッドが65535回以上再帰的にロックを取得しようとする曖昧なケースでErrorをスローします。

+0

okです。右。 sun(oracle)の公式コード例間違ってはならない。 –

6

それは良い防御プログラミングです。ボディがOutOfMemoryErrorなど、何らかの理由で例外をスローするようにコードが変更された場合、ロックを固執したままにしないとうれしいでしょう。

私は個人的に(B)に行くだろう - もしlock()メソッド自体が例外をスローするなら、それはまだバランスがとれていただろう。しかし、実際にはそれほど重要ではないと私は考えています。

関連する問題