Wiki Markup |
---|
Code that uses synchronization can sometimes be enigmatic and tricky to debug. Misuse of synchronization primitives is a common source of implementation errors. An analysis of the JDK 1.6.0 source code unveiled at least 31 bugs that fell into this category. \[[Pugh 08|AA. Java References#Pugh 08]\] |
There are several common oversights and programming errors with synchronizing on objectsassociated with the improper use of locks, for example:
- The lock object might be accessible to hostile code that can acquire the lock and hold it indefinitely.
- A non-final lock is mutable and consequently, unfit for synchronization synchronization might be on a non-final field. When the lock field is modified to reference refer to a different object, threads that synchronize on the field no longer maintain exclusive locks, and run the danger of executing critical sections of code simultaneouslyThe lock object might be accessible to hostile code, which can obtain the lock and hold it indefinitelylose their mutual exclusion rights.
Noncompliant Code Example (public
nonfinal lock object)
...
This is because the thread that holds a lock on the nonfinal field object can modify the field's value to reference some other object. This might cause two threads that lock on the same field to actually not lock on the same object, causing them to execute critical sections of code simultaneously.
Compliant Solution (private
and final
lock object)
This compliant solution synchronizes using a lock object that is declared as final
.
Code Block |
---|
|
private final Integer lock = new Integer(0);
private void doSomething() {
synchronized(lock) { /* ... */ }
}
// setValue() is disallowed
|
Noncompliant Code Example (Boolean
lock object)
Wiki Markup |
---|
This noncompliant code example uses a {{Boolean}} field to synchronize. However, sincebecause the field is not {{final}}non-final, there can be two possible valid values ({{true}} and {{false}}, discounting {{null}}) that a {{Boolean}} can assume. Consequently, any other code that synchronizes on the same value can cause unresponsiveness and deadlocks \[[Findbugs 08|AA. Java References#Findbugs 08]\]. |
Code Block |
---|
|
private Boolean initialized = Boolean.FALSE;
synchronized(initialized) {
if (!initialized) {
// Perform initialization
initialized = Boolean.TRUE;
}
}
|
Compliant Solution (private
and final
lock object)
This compliant solution synchronizes using a lock object that is declared as final
.
Code Block |
---|
|
private final Integer lock = new Integer(0);
private void doSomething() {
synchronized(lock) { /* ... */ }
}
// setValue() is disallowed
|
Noncompliant Code Example (Boxed primitive)
...