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="8b3006cb-9486-4ea5-9830-3dffe4c198f9"><ac:plain-text-body><![CDATA[ |
[[API 2006 |
AA. References#API 06]] |
|
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="36dc73c5-967a-4433-9717-800e97d90465"><ac:plain-text-body><![CDATA[ |
[[Findbugs 2008 |
AA. References#Findbugs 08]] |
|
]]></ac:plain-text-body></ac:structured-macro> |
|
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="4c3aad98-ba97-41d9-81ba-f75b84db6eb2"><ac:plain-text-body><![CDATA[ |
[[Pugh 2008 |
AA. References#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="aa3a1709-3546-40c0-9b5a-ebc8dfca246d"><ac:plain-text-body><![CDATA[ |
[[Miller 2009 |
AA. References#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="efb402f7-1c3f-4ae0-8a40-afa677cbcab8"><ac:plain-text-body><![CDATA[ |
[[Tutorials 2008 |
AA. References#Tutorials 08]] |
[Wrapper Implementations |
http://java.sun.com/docs/books/tutorial/collections/implementations/wrapper.html] |
]]></ac:plain-text-body></ac:structured-macro> |