Wiki Markup |
---|
The {{java.util.Collections}} interface's documentation \[[API 06|AA. Java References#API 06]\] warns about the consequences of synchronizingfailing onto anysynchronize viewon overan aaccessible collection object, ratherwhen thaniterating synchronizingover on the collection object itself.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.
...
Wiki Markup |
---|
This noncompliant code example creates two views, a synchronized view of an empty map, which is heldencapsulated by the {{map}} field, and a set view of the map's keys, which is heldencapsulated by the {{set}} field. Furthermore, this code synchronizes on the {{set}} view instead of the more accessible {{map}} view \[[Tutorials 08|AA. Java References#Tutorials 08]\]. |
...
This compliant solution synchronizes on the map
view instead of the set
view. This is safe because the origianl map (created by new HashMap()
) is not accessible and hence unmodifiable except via the map
fieldcompliant because the iterator cannot fail as a result of changes in the map's structure when an iteration is in progress.
Code Block | ||
---|---|---|
| ||
// 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) { // ... } } } |
...