This is an automated email from the ASF dual-hosted git repository.
garydgregory pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-collections.git
The following commit(s) were added to refs/heads/master by this push:
new 487834079 [COLLECTIONS-894] Document thread-safety limitations of
map-backed Bag and MultiSet implementations (#707)
487834079 is described below
commit 487834079eeed9444ae25b232e902e6185f82ad1
Author: Paul King <[email protected]>
AuthorDate: Fri Jul 10 22:25:13 2026 +1000
[COLLECTIONS-894] Document thread-safety limitations of map-backed Bag and
MultiSet implementations (#707)
---
src/main/java/org/apache/commons/collections4/bag/HashBag.java | 10 ++++++++++
src/main/java/org/apache/commons/collections4/bag/TreeBag.java | 9 +++++++++
.../org/apache/commons/collections4/multiset/HashMultiSet.java | 10 ++++++++++
.../org/apache/commons/collections4/multiset/TreeMultiSet.java | 9 +++++++++
4 files changed, 38 insertions(+)
diff --git a/src/main/java/org/apache/commons/collections4/bag/HashBag.java
b/src/main/java/org/apache/commons/collections4/bag/HashBag.java
index e22def4bf..d968c3613 100644
--- a/src/main/java/org/apache/commons/collections4/bag/HashBag.java
+++ b/src/main/java/org/apache/commons/collections4/bag/HashBag.java
@@ -33,6 +33,16 @@ import java.util.HashMap;
* interface Javadoc carefully as several methods violate the
* {@link Collection} interface specification.
* </p>
+ * <p>
+ * <strong>Note that HashBag is not synchronized and is not
thread-safe.</strong>
+ * If you wish to use this bag from multiple threads concurrently, you must use
+ * appropriate synchronization. The simplest approach is to wrap this bag using
+ * {@link
org.apache.commons.collections4.BagUtils#synchronizedBag(org.apache.commons.collections4.Bag)
+ * BagUtils.synchronizedBag(Bag)}.
+ * Unsynchronized concurrent modification can corrupt the structure of the
backing
+ * {@link HashMap}, which may cause subsequent operations to throw exceptions,
+ * return incorrect results, or loop indefinitely.
+ * </p>
*
* @param <E> The type of elements in this bag
* @since 3.0 (previously in main package v2.0)
diff --git a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java
b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java
index bc474313b..e1b60df63 100644
--- a/src/main/java/org/apache/commons/collections4/bag/TreeBag.java
+++ b/src/main/java/org/apache/commons/collections4/bag/TreeBag.java
@@ -40,6 +40,15 @@ import org.apache.commons.collections4.SortedBag;
* copies of an object to be added or removed at once. It is important to read
the interface
* Javadoc carefully as several methods violate the {@link Collection}
interface specification.
* </p>
+ * <p>
+ * <strong>Note that TreeBag is not synchronized and is not
thread-safe.</strong>
+ * If you wish to use this bag from multiple threads concurrently, you must use
+ * appropriate synchronization. The simplest approach is to wrap this bag using
+ * {@link
org.apache.commons.collections4.BagUtils#synchronizedSortedBag(SortedBag)}.
+ * Unsynchronized concurrent modification can corrupt the structure of the
backing
+ * {@link TreeMap}, and a malformed tree may cause subsequent operations,
including
+ * reads, to enter an infinite loop.
+ * </p>
*
* @param <E> The type of elements in this bag
* @since 3.0 (previously in main package v2.0)
diff --git
a/src/main/java/org/apache/commons/collections4/multiset/HashMultiSet.java
b/src/main/java/org/apache/commons/collections4/multiset/HashMultiSet.java
index 25b5c2dae..c31cbec9e 100644
--- a/src/main/java/org/apache/commons/collections4/multiset/HashMultiSet.java
+++ b/src/main/java/org/apache/commons/collections4/multiset/HashMultiSet.java
@@ -31,6 +31,16 @@ import java.util.HashMap;
* count of occurrences. Extra methods on the interface allow multiple copies
* of an object to be added or removed at once.
* </p>
+ * <p>
+ * <strong>Note that HashMultiSet is not synchronized and is not
thread-safe.</strong>
+ * If you wish to use this multiset from multiple threads concurrently, you
must use
+ * appropriate synchronization. The simplest approach is to wrap this multiset
using
+ * {@link
org.apache.commons.collections4.MultiSetUtils#synchronizedMultiSet(org.apache.commons.collections4.MultiSet)
+ * MultiSetUtils.synchronizedMultiSet(MultiSet)}.
+ * Unsynchronized concurrent modification can corrupt the structure of the
backing
+ * {@link HashMap}, which may cause subsequent operations to throw exceptions,
+ * return incorrect results, or loop indefinitely.
+ * </p>
*
* @param <E> The type held in the multiset
* @since 4.1
diff --git
a/src/main/java/org/apache/commons/collections4/multiset/TreeMultiSet.java
b/src/main/java/org/apache/commons/collections4/multiset/TreeMultiSet.java
index 1e5330ee1..29153b9f5 100644
--- a/src/main/java/org/apache/commons/collections4/multiset/TreeMultiSet.java
+++ b/src/main/java/org/apache/commons/collections4/multiset/TreeMultiSet.java
@@ -40,6 +40,15 @@ import org.apache.commons.collections4.SortedMultiSet;
* count of occurrences. Extra methods on the interface allow multiple copies
* of an object to be added or removed at once.
* </p>
+ * <p>
+ * <strong>Note that TreeMultiSet is not synchronized and is not
thread-safe.</strong>
+ * If you wish to use this multiset from multiple threads concurrently, you
must use
+ * appropriate synchronization. The simplest approach is to wrap this multiset
using
+ * {@link
org.apache.commons.collections4.MultiSetUtils#synchronizedSortedMultiSet(SortedMultiSet)}.
+ * Unsynchronized concurrent modification can corrupt the structure of the
backing
+ * {@link TreeMap}, and a malformed tree may cause subsequent operations,
including
+ * reads, to enter an infinite loop.
+ * </p>
*
* @param <E> The type held in the multiset
* @since 4.6.0