Programs must not lock on an object of a class that implements either or both of the Lock
and Condition
interfaces of the java.util.concurrent.locks
package. Using the intrinsic locks of these classes is a questionable practice even in cases where the code may appear to function correctly. This problem generally arises when code is refactored from intrinsic locking to the java.util.concurrent
dynamic-locking utilities.
Noncompliant Code Example (ReentrantLock
Lock Object)
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 because the class can end up with two different 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="fa771e98-e5cc-4e53-a53c-2e806f36e911"><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="6808475c-42d0-4b5b-8c86-8cc0426ec393"><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="674c6079-4705-4396-af7b-cb84036a376d"><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="17ac7e72-6b61-4d83-9de9-fcdddaace78d"><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="9ab82466-0b55-487a-842c-70a2c9ccb09a"><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> |