Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

This noncompliant code example locks on a boxed Integer object.

Code Block
bgColor#FFcccc
private int lockcount = 0;
private final Integer Lock = lockcount; // Boxed primitive Lock is shared

public void doSomething() {
  synchronized (Lock) {
    count++;
    // ...
  }
}

Boxed types may use the same instance for a range of integer values; consequently, they suffer from the same reuse problem as Boolean constants. The wrapper object are reused when the value can be represented as a byte; JVM implementations are also permitted to reuse wrapper objects for larger ranges of values. While use of the intrinsic lock associated with the boxed Integer wrapper object is insecure; instances of the Integer object constructed using the new operator (new Integer(value)) are unique and not reused. In general, locks on any data type that contains a boxed value are insecure.

...

This compliant solution locks on a nonboxed Integer, using a variant of the private lock object idiom. The doSomething() method synchronizes using the intrinsic lock of the Integer instance, Lock.

Code Block
bgColor#ccccff
private int lockcount = 0;
private final Integer Lock = new Integer(lockcount);

public void doSomething() {
  synchronized (Lock) {
    count++;
    // ...
  }
}

When explicitly constructed, an Integer object has a unique reference and its own intrinsic lock that is distinct not only from other Integer objects, but also from boxed integers that have the same value. While this is an acceptable solution, it can cause maintenance problems because developers can incorrectly assume that boxed integers are also appropriate lock objects. A more appropriate solution is to synchronize on a private final lock object as described in the final compliant solution for this rule.

...