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. Code that uses the intrinsic lock of a Lock object is likely to interact with code that uses the Lock interface. These two components will believe they are protecting data with the same lock, while they are, in fact, using two distinct locks. As such, the Lock will fail to protect any data.
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.
...
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.
| Code Block | ||
|---|---|---|
| ||
private final Lock lock = new ReentrantLock();
public void doSomething() {
synchronized(lock) {
// ...
}
}
|
...
This compliant solution uses the lock() and unlock() methods provided by the Lock interface.
| Code Block | ||
|---|---|---|
| ||
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 use other concurrency primitives such as synchronization and atomic classes.
...
Synchronizing on the intrinsic lock of high-level concurrency utilities can cause nondeterministic behavior resulting from inconsistent locking policies.
Rule | Severity | Likelihood |
|---|
Detectable | Repairable | Priority | Level |
|---|---|---|---|
LCK03-J | medium | probable | Yes |
No | P8 | L2 |
Bibliography
<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="490ebd31-16b0-423b-bd52-d5fbb8847954"><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="2a2fc048-44c7-40b5-8444-d046ee8cb0b8"><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="ef3f843e-8a40-4af4-86d5-45ab90288282"><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="170de3e9-fca3-4d5e-989c-3fc2399514fd"><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="c4c75154-20e3-4730-ae64-da1421a07d94"><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> |
Automated Detection
| Tool | Version | Checker | Description | ||||||
|---|---|---|---|---|---|---|---|---|---|
| PVS-Studio |
| V6126 | |||||||
| SonarQube |
| S2442 | Implemented |
Bibliography
[API 2006] | |
Synchronization | |
Locking | |
...