Closed
Description
Calling the DefaultMessageListenerContainer#remove(Subscription)
method from multiple threads results in ConcurrentModificationException
within the LinkedHashIterator
. This issue arises due to the use of a read lock during collection modification.
The changes made in Pull Request #4431 are the cause of this issue. Class members lifecycleWrite
and subscriptionWrite
are assigned a read lock, not a write lock.
private final Lock lifecycleWrite = Lock.of(lifecycleMonitor.readLock());
private final Lock subscriptionWrite = Lock.of(subscriptionMonitor.readLock());
Exception stacktrace:
java.util.ConcurrentModificationException: null
at java.base/java.util.LinkedHashMap$LinkedHashIterator.nextNode(LinkedHashMap.java:764) ~[na:na]
at java.base/java.util.LinkedHashMap$LinkedValueIterator.next(LinkedHashMap.java:791) ~[na:na]
at java.base/java.util.AbstractCollection.remove(AbstractCollection.java:284) ~[na:na]
at org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer.lambda$remove$8(DefaultMessageListenerContainer.java:203) ~[spring-data-mongodb-4.2.3.jar:4.2.3] at org.springframework.data.util.Lock.executeWithoutResult(Lock.java:119) ~[spring-data-commons-3.2.3.jar:3.2.3]
at org.springframework.data.mongodb.core.messaging.DefaultMessageListenerContainer.remove(DefaultMessageListenerContainer.java:195) ~[spring-data-mongodb-4.2.3.jar:4.2.3]