Wiki Markup |
---|
Misuse of synchronization primitives is a common source of concurrency issues. A significant number of concurrency vulnerabilities arise from locking on the wrong kind of object. 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]\]. It is important to recognize the entities with whom synchronization is required rather than indiscreetly scavenging for variables or objects to synchronize on. |
...
Wiki Markup |
---|
There can only be two possible valid values - ({{true}} and {{false}}, (discounting {{null}}) that {{initialized}} can assume. Consequently, any other code that synchronizes on a {{Boolean}} variable with the same value, may induce unresponsiveness and deadlocks \[[Findbugs 08|AA. Java References#Findbugs 08]\]. |
...
Boxed types are allowed to use the same instance for a range of integer values and consequently, suffer from the same problem as Boolean
constants. If the value of the primitive can be represented as a byte, the wrapper object is reused. Note that the use of the boxed Integer
wrapper object is shared and not an instance insecure; instances of the Integer
object constructed using the new
operator (new Integer(value)
) itselfare unique and not reused. In general, holding a lock on any data type that contains a boxed value is insecure.
Compliant Solution (Integer)
This compliant solution locks recommends locking on a non-boxed Integer. The doSomething()
method synchronizes using the intrinsic lock of the Integer
instance, Lock
.
...
This compliant solution uses an internal private final lock object. This is one of the few cases where a raw java.lang.Object
instance is useful.
Code Block | ||
---|---|---|
| ||
private final Object lock = new Object(); public void doSomething() { synchronized(lock) { // ... } } |
...
Code Block | ||
---|---|---|
| ||
public void doSomething() { synchronized(SuperclassName.class) { // ... } } |
The class object that is being synchronized used for synchronization should not be accessible to hostile code. If the class is package-private, then callers from other packages may not access the Class class object, ensuring its trustworthiness as an intrinsic lock object. For more information, see CON04-J. Synchronize using an internal private final lock object.
...
Code Block | ||
---|---|---|
| ||
public void doSomething() { synchronized(Class.forName("SuperclassName")) { // ... } } |
The class object that is being synchronized used for synchronization should not be accessible to hostile code, as discussed in the previous compliant solution. Furthermore, care must be taken so to ensure that untrusted inputs are not accepted as arguments while loading classes using Class.forname()
. (see See SEC05-J. Do not expose standard APIs that use the immediate caller's class loader instance to untrusted code for more information.).
Noncompliant Code Example (ReentrantLock
lock object)
...
Wiki Markup |
---|
The {{java.util.Collections}} interfacesinterface's documentation \[[API 06|AA. Java References#API 06]\] supports warns about the consequences of following this recommendationpractice: |
It is imperative that the user manually synchronize on the returned map when iterating over any of its collection views... Failure to follow this advice may result in non-deterministic behavior.
...