...
This noncompliant code example locks on a nonfinal object that is declared public
. It is possible that for untrusted code can to change the value of the lock object and foil any attempts to synchronize.
...
Code Block | ||
---|---|---|
| ||
// This bug was found in jetty-6.1.3 BoundedThreadPool
private final String _lock = "one";
synchronized(_lock) { /* ... */ }
|
Noncompliant Code Example
This noncompliant code example locks on a boxed Integer
object.
Code Block | ||
---|---|---|
| ||
int lock = 0; Integer Lock = lock; // Boxed primitive Lock will be shared synchronized(Lock) { /* ... */ } |
Boxed types may use the same instance for a range of integer values and consequently, suffer from the same problems as String
constants. Note that the boxed Integer
primitive is shared and not the Integer
object (new Integer(value)
) itself. In general, holding a lock on any data structure that contains a boxed value is insecure.
Noncompliant Code Example (Mutable lock object)
This noncompliant code example synchronizes on a mutable field instead of an object a raw Object
and demonstrates no mutual exclusion properties.
Code Block | ||
---|---|---|
| ||
private Integer semaphore = new Integer(0);
synchronized(semaphore) { /* ... */ }
|
This is because the thread that holds a lock on the field can modify the referenced object's value which allows , allowing another thread that is blocked on the unmodified value to resume, at the same time, granting access to contending for the lock with a third thread that is blocked on the modified value. When aiming to modify a field, it is incorrect It is insecure to synchronize on the same (or another) field as a mutable field because this is equivalent to synchronizing on the field's contents.
Code Block | ||
---|---|---|
| ||
private Integer semaphore = new Integer(0);
synchronized(semaphore) { /* ... */ }
|
This is a mutual exclusion problem as opposed to the sharing issue discussed in the previous noncompliant code example. Note that the boxed Integer
primitive is shared as shown below and not the Integer
object (new Integer(value)
) itself.
...
...
int lock = 0;
Integer Lock = lock; // Boxed primitive Lock will be shared
In general, holding a lock on any data structure that contains a boxed value can be dangerous.
Noncompliant Code Example (Boolean
lock object)
Wiki Markup |
---|
This noncompliant code example uses a {{Boolean}} field to synchronize. However, there can only be two possible valid values ({{true}} and {{false}}) 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]\]. |
...
Note that the instance of the raw object should not be changed from within the synchronized block. For example, creating and storing the reference of a new object into the lock
field is highly inadvisable. To prevent such modifications, declare the lock
field as final
.
Noncompliant Code Example (getClass()
lock object)
Synchronizing on getClass()
rather than a class literal can also be counterproductive. Whenever the implementing class is subclassed, the subclass locks on a completely different Class
object (subclass's type).
Code Block | ||
---|---|---|
| ||
synchronized(getClass()) { /* ... */ } |
Wiki Markup |
---|
This idea is sometimes easy to miss, especially when the Java Language Specification is misunderstood. Section 4.3.2 "The Class Object" of the specification \[[JLS 05|AA. Java References#JLS 05]\] describes how method synchronization works: |
A class method that is declared
synchronized
synchronizes on the lock associated with theClass
object of the class.
This does not mean that it is required to a subclass can only synchronize on the Class
object of the base class.
...
Explicitly define the name of the class through name qualification (superclass in this example) in the synchronization block. This can be achieved in two ways. One way is to explicitly pass the superclass's instance.
Code Block | ||
---|---|---|
| ||
synchronized(SuperclassName.class) { // ... } |
Compliant Solution (2) (Class.forName()
)
The second way is to use This compliant solution uses the Class.forName()
method to synchronize on the superclass's Class
object.
Code Block | ||
---|---|---|
| ||
synchronized(Class.forName("SuperclassName")) { // ... } |
Finally, it is more important to recognize the entities with whom synchronization is required rather than indiscreetly scavenging for variables or objects to synchronize on.
...