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

Reply via email to