diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java index fb91071666a..7394c6a28ef 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/balancer/Dispatcher.java @@ -40,6 +40,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -405,7 +406,8 @@ public class Dispatcher { // Pinned block can't be moved. Add this block into failure list. // Later in the next iteration mover will exclude these blocks from // pending moves. - target.getDDatanode().addBlockPinningFailures(this); + target.getDDatanode().addBlockPinningFailures( + this.reportedBlock.getBlock().getBlockId(), this.getSource()); return; } @@ -643,7 +645,8 @@ public class Dispatcher { /** blocks being moved but not confirmed yet */ private final List pendings; private volatile boolean hasFailure = false; - private Map> blockPinningFailures = new HashMap<>(); + private final Map> blockPinningFailures = + new ConcurrentHashMap<>(); private volatile boolean hasSuccess = false; private ExecutorService moveExecutor; @@ -729,16 +732,17 @@ public class Dispatcher { this.hasFailure = true; } - void addBlockPinningFailures(PendingMove pendingBlock) { - synchronized (blockPinningFailures) { - long blockId = pendingBlock.reportedBlock.getBlock().getBlockId(); - Set pinnedLocations = blockPinningFailures.get(blockId); + private void addBlockPinningFailures(long blockId, DatanodeInfo source) { + blockPinningFailures.compute(blockId, (key, pinnedLocations) -> { + Set newPinnedLocations; if (pinnedLocations == null) { - pinnedLocations = new HashSet<>(); - blockPinningFailures.put(blockId, pinnedLocations); + newPinnedLocations = new HashSet<>(); + } else { + newPinnedLocations = pinnedLocations; } - pinnedLocations.add(pendingBlock.getSource()); - } + newPinnedLocations.add(source); + return newPinnedLocations; + }); } Map> getBlockPinningFailureList() {