java.util.concurrent.locks パッケージのインタフェース Lock および Condition のいずれか、あるいは両方を実装するクラスのインスタンスは、高水準な並行処理オブジェクトである。これらのオブジェクトの固有ロックを使用することは、たとえコードが正しく機能するように見えるとしても、推奨されない。したがって、これらのオブジェクトとのやり取りを行うプログラムは、java.util.concurrent.locks パッケージのインタフェースが提供する高水準のロック機能のみを使用しなくてはならない。オブジェクトの固有ロックを使用してはならない。この問題は多くの場合、固有ロックを使用するコードを java.util.concurrent の動的ロックユーティリティを使用するように修正するときに発生する。
違反コード (ReentrantLockオブジェクト)
以下の違反コード例の doSomething() メソッドでは、ReentrantLock によりカプセル化された再入可能な排他ロックを使用するのではなく、ReentrantLock インスタンスの固有ロックを使用して同期を行っている。
private final Lock lock = new ReentrantLock(); public void doSomething() { synchronized(lock) { // ... } }
適合コード (lock()とunlock()メソッドの使用)
以下の適合コードでは、Lock インタフェースが提供する lock() メソッドと unlock() メソッドを使用している。
private final Lock lock = new ReentrantLock(); public void doSomething() { lock.lock(); try { // ... } finally { lock.unlock(); } }
java.util.concurrent パッケージの動的ロックユーティリティが提供する高度な機能が不要な場合、Executor フレームワークを使用するか、同期クラスやアトミッククラスといった、その他の並行処理用のプリミティブを使用する方がよい。
リスク評価
高水準な並行処理ユーティリティの固有ロックを使って同期を行うと、複数のロックポリシーが混在することになり、プログラムの予測できない動作を引き起こす可能性がある。
ルール | 深刻度 | 可能性 | 修正コスト | 優先度 | レベル |
---|---|---|---|---|---|
LCK03-J | 中 | 中 | 中 | P8 | L2 |
参考文献
[API 2006] | |
[Findbugs 2008] | |
[Pugh 2008] | Synchronization |
[Miller 2009] | Locking |
[Tutorials 2008] | Wrapper Implementations |
翻訳元
これは以下のページを翻訳したものです。
LCK03-J. Do not synchronize on the intrinsic locks of high-level concurrency objects (revision 40)