...
Boxed types are allowed to use the same instance for a range of integer values and consequently, suffer from the same problems as Boolean
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.
Compliant Solution (Integer)
This compliant solution locks on a (non-boxed) Integer. When explicitly constructed, an Integer
object has a unique reference and its own intrinsic lock, not shared by other integers, autoboxed or not.
Code Block | ||
---|---|---|
| ||
int lock = 0;
final Integer Lock = new Integer( lock);
synchronized(Lock) { /* ... */ }
|
Noncompliant Code Example (String
...
literal)
This noncompliant code example locks on a final String
literal.
...
Consequently, a String
constant behaves like a global variable in the JVM. As demonstrated in this noncompliant code example, even if every instance of an object maintains its own field lock
, the field points to a common String
constant in the JVM. Trusted code that locks on the same String
constant renders all synchronization attempts inadequate. Likewise, hostile code from any other package can exploit this vulnerability.
Compliant Solution (
...
new String)
This compliant solution uses an internal private lock object. This is one of the few cases where a raw Object
is useful. Private lock objects are discussed in CON04-J. Synchronize using an internal private lock object.locks on a String
explicitly constructed. This String
object has a unique reference and its own intrinsic lock, not shared by other strings.
Code Block | ||
---|---|---|
| ||
private final ObjectString _lock = new ObjectString("LOCK"); synchronized(_lock) { //* ... */ } |
Noncompliant Code Example (getClass()
lock object)
...