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.
Synchronize on the original collection object when using synchronization wrappers to enforce atomicity (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
Review List
VOID CON00-J. Synchronize access to shared mutable variables 11. Concurrency (CON) CON03-J. Do not use background threads during class initialization