@@ -62,6 +62,8 @@ Race conditions
62
62
] ( #unsafe-concurrent-iteration )
63
63
- [ A non-thread-safe collection is * not* returned wrapped in ` Collections.unmodifiable*() ` from
64
64
a getter in a thread-safe class?] ( #unsafe-concurrent-iteration )
65
+ - [ A synchronized collection is not returned from a getter? in a thread-safe class?
66
+ ] ( #unsafe-concurrent-iteration )
65
67
- [ Non-trivial mutable object is * not* returned from a getter in a thread-safe class?
66
68
] ( #concurrent-mutation-race )
67
69
- [ No separate getters to an atomically updated state?] ( #moving-state-race )
@@ -78,7 +80,9 @@ Race conditions
78
80
- [ Concurrent invalidation race is not possible on a lazily initialized state?
79
81
] ( #cache-invalidation-race )
80
82
- [ Iteration, Stream pipeline, or copying a ` Collections.synchronized*() ` collection is protected
81
- by a lock?] ( #synchronized-collection-iter )
83
+ by the lock?] ( #synchronized-collection-iter )
84
+ - [ A synchronized collection is passed into ` addAll() ` , ` removeAll() ` , or ` putAll() ` under the
85
+ lock?] ( #synchronized-collection-iter )
82
86
83
87
Testing
84
88
- [ Unit tests for thread-safe classes are multi-threaded?] ( #multi-threaded-tests )
@@ -717,9 +721,21 @@ more scalable than Guava Cache: see [Sc.9](#caffeine).
717
721
Stream pipeline using a synchronized collection as a source is protected by ` synchronized (coll) ` ?**
718
722
See [ the Javadoc] (
719
723
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Collections.html#synchronizedCollection(java.util.Collection) )
720
- for examples and details. This also applies to passing synchronized collections into copy
721
- constructors or static factory methods of other collections because they implicitly iterate over the
722
- source collection.
724
+ for examples and details.
725
+
726
+ This also applies to passing synchronized collections into:
727
+ - Copy constructors of other collections, e. g. ` new ArrayList<>(synchronizedList) `
728
+ - Static factory methods of other collections, e. g. ` List.copyOf() ` , ` Set.copyOf() ` ,
729
+ ` ImmutableMap.copyOf() `
730
+ - Bulk methods on other collections:
731
+ - ` otherColl.containsAll(synchronizedColl) `
732
+ - ` otherColl.addAll(synchronizedColl) `
733
+ - ` otherColl.removeAll(synchronizedColl) `
734
+ - ` otherMap.putAll(synchronizedMap) `
735
+ - ` otherColl.containsAll(synchronizedMap.keySet()) `
736
+ - Etc.
737
+
738
+ Because in all these cases there is an implicit iteration on the source collection.
723
739
724
740
See also [ RC.3] ( #unsafe-concurrent-iteration ) about unprotected iteration over non-thread-safe
725
741
collections.
0 commit comments