Instances of classes that implement either or both of the Lock
and Condition
interfaces of the java.util.concurrent.locks
package are known as high-level concurrency objects. Using the intrinsic locks of such objects is a questionable practice even in cases where the code may appear to function correctly. Consequently, programs that interact with such objects must use only the high-level locking facilities provided by the interfaces; use of the intrinsic locks is prohibited. This problem generally arises when code is refactored from intrinsic locking to the java.util.concurrent
dynamic-locking utilities.
Noncompliant Code Example (ReentrantLock
)
The doSomething()
method in this noncompliant code example synchronizes on the intrinsic lock of an instance of ReentrantLock
rather than on the reentrant mutual exclusion Lock
encapsulated by ReentrantLock
.
private final Lock lock = new ReentrantLock(); public void doSomething() { synchronized(lock) { // ... } }
Compliant Solution (lock()
and unlock()
)
This compliant solution uses the lock()
and unlock()
methods provided by the Lock
interface.
private final Lock lock = new ReentrantLock(); public void doSomething() { lock.lock(); try { // ... } finally { lock.unlock(); } }
In the absence of a requirement for the advanced functionality of the java.util.concurrent
package's dynamic-locking utilities, it is better to use the Executor
framework or other concurrency primitives such as synchronization and atomic classes.
Risk Assessment
Synchronizing on the intrinsic lock of high-level concurrency utilities can cause nondeterministic behavior resulting from inconsistent locking policies.
Rule |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
LCK03-J |
medium |
probable |
medium |
P8 |
L2 |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e98af53f-69a6-4a19-b5b9-8786e574bac4"><ac:plain-text-body><![CDATA[ |
[[API 2006 |
AA. Bibliography#API 06]] |
|
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="92480a81-6554-4626-ab71-3d573d1edcaa"><ac:plain-text-body><![CDATA[ |
[[Findbugs 2008 |
AA. Bibliography#Findbugs 08]] |
|
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="e53bae7d-6c52-4987-8180-a52f00c24097"><ac:plain-text-body><![CDATA[ |
[[Pugh 2008 |
AA. Bibliography#Pugh 08]] |
Synchronization |
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="13cf8294-3a81-49d5-9809-76870dd22b72"><ac:plain-text-body><![CDATA[ |
[[Miller 2009 |
AA. Bibliography#Miller 09]] |
Locking |
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="16b35838-cc83-4cb7-8c1a-a9e021c92268"><ac:plain-text-body><![CDATA[ |
[[Tutorials 2008 |
AA. Bibliography#Tutorials 08]] |
[Wrapper Implementations |
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html] |
]]></ac:plain-text-body></ac:structured-macro> |