You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 36 Next »

The java.util.Collections interface's documentation [[API 06]] warns about the consequences of failing to synchronize on an accessible collection object when iterating over its view:

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.

To make a group of statements atomic, synchronize on the original collection object when using synchronization wrappers.(CON07-J. Do not assume that a group of calls to independently atomic methods is atomic).

Noncompliant Code Example (collection view)

This noncompliant code example creates two views, a synchronized view of an empty map encapsulated by the map field, and a set view of the map's keys encapsulated by the set field. Furthermore, this code synchronizes on the set view instead of the more accessible map view [[Tutorials 08]].

// map has package-private accessibility
final Map<Integer, String> map = Collections.synchronizedMap(new HashMap<Integer, String>());
private final Set<Integer> set = map.keySet();

public void doSomething() {
  synchronized(set) {  // Incorrectly synchronizes on set
    for (Integer k : set) { 
      // ...
    }
  }
}

If the set is synchronized instead of the map, another thread may modify the contents of the map, and invalidate the k iterator.

Compliant Solution (collection lock object)

This compliant solution synchronizes on the map view instead of the set view. This is compliant because the iterator cannot fail as a result of changes in the map's structure when an iteration is in progress.

// map has package-private accessibility
final Map<Integer, String> map = Collections.synchronizedMap(new HashMap<Integer, String>());
private final Set<Integer> set = map.keySet();

public void doSomething() {
  synchronized(map) {  // Synchronize on map, not set
    for (Integer k : set) { 
      // ...
    }
  }
}

Risk Assessment

Synchronizing on a collection view instead of the collection object may cause non-deterministic behavior.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

CON40-J

medium

probable

medium

P8

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

[[API 06]] Class Collections
[[Tutorials 08]] Wrapper Implementations

Issue Tracking

0%

Review List


VOID CON00-J. Synchronize access to shared mutable variables      11. Concurrency (CON)      CON03-J. Do not use background threads during class initialization

  • No labels