From f164fab4166d408e86233c7ee54ca8835bbbf220 Mon Sep 17 00:00:00 2001 From: abilan Date: Wed, 7 Jun 2023 17:31:35 -0400 Subject: [PATCH] Optimize synchronized in PartitionedDispatcher Even if the `PartitionedDispatcher.populatedPartitions()` is fast, in-memory, non-blocking operation, its active call from the `dispatch()` on every message sent to the channel may pin the virtual thread. * Optimize the `populatedPartitions()` for double `if` where we will step into a `synchronized` block only for first several concurrent messages **Cherry-pick to `6.1.x`** --- .../dispatcher/PartitionedDispatcher.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/PartitionedDispatcher.java b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/PartitionedDispatcher.java index 2b727ac61ad..1883f190fa1 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/PartitionedDispatcher.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/dispatcher/PartitionedDispatcher.java @@ -151,10 +151,16 @@ public boolean dispatch(Message message) { return partitionDispatcher.dispatch(message); } - private synchronized void populatedPartitions() { + private void populatedPartitions() { if (this.partitions.isEmpty()) { - for (int i = 0; i < this.partitionCount; i++) { - this.partitions.put(i, newPartition()); + synchronized (this.partitions) { + if (this.partitions.isEmpty()) { + Map partitionsToUse = new HashMap<>(); + for (int i = 0; i < this.partitionCount; i++) { + partitionsToUse.put(i, newPartition()); + } + this.partitions.putAll(partitionsToUse); + } } } }