Skip to content

Commit f8c699b

Browse files
committed
Safely add and register the MessageListener to Topic mapping.
Given addListener(:MessageListener, :Collection<Topic>) could be called concurrently from the addMessageListener(:MessageListener, Collection<Topic>) method by multiple Threads, and the RedisMessageListenerContainer Javadoc specifically states that it is safe to call the addMessageListener(..) method conurrently without any external synchronization, and the registeration (or mapping) of listener to Topics is a componund action, then a race condition is possible. Closes #2755
1 parent 963bc92 commit f8c699b

File tree

1 file changed

+5
-8
lines changed

1 file changed

+5
-8
lines changed

src/main/java/org/springframework/data/redis/listener/RedisMessageListenerContainer.java

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -612,20 +612,17 @@ private void initMapping(Map<? extends MessageListener, Collection<? extends Top
612612

613613
private void addListener(MessageListener listener, Collection<? extends Topic> topics) {
614614

615-
Assert.notNull(listener, "a valid listener is required");
616-
Assert.notEmpty(topics, "at least one topic is required");
615+
Assert.notNull(listener, "A valid listener is required");
616+
Assert.notEmpty(topics, "At least one topic is required");
617617

618618
List<byte[]> channels = new ArrayList<>(topics.size());
619619
List<byte[]> patterns = new ArrayList<>(topics.size());
620620

621621
boolean trace = logger.isTraceEnabled();
622622

623-
// add listener mapping
624-
Set<Topic> set = listenerTopics.get(listener);
625-
if (set == null) {
626-
set = new CopyOnWriteArraySet<>();
627-
listenerTopics.put(listener, set);
628-
}
623+
// safely lookup or add MessageListener to Topic mapping
624+
Set<Topic> set = listenerTopics.computeIfAbsent(listener, key -> new CopyOnWriteArraySet<>());
625+
629626
set.addAll(topics);
630627

631628
for (Topic topic : topics) {

0 commit comments

Comments
 (0)