diff --git a/hadoop-mapreduce-project/CHANGES.txt b/hadoop-mapreduce-project/CHANGES.txt index fce417bad6..4a89be511e 100644 --- a/hadoop-mapreduce-project/CHANGES.txt +++ b/hadoop-mapreduce-project/CHANGES.txt @@ -352,6 +352,9 @@ Release 0.23.3 - UNRELEASED MAPREDUCE-4220. RM apps page starttime/endtime sorts are incorrect (Jonathan Eagles via bobby) + MAPREDUCE-4226. ConcurrentModificationException in FileSystemCounterGroup. + (tomwhite) + Release 0.23.2 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/counters/FileSystemCounterGroup.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/counters/FileSystemCounterGroup.java index 7c23561b65..3f3729fb05 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/counters/FileSystemCounterGroup.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/main/java/org/apache/hadoop/mapreduce/counters/FileSystemCounterGroup.java @@ -23,6 +23,7 @@ import java.io.IOException; import java.util.Arrays; import java.util.concurrent.ConcurrentMap; +import java.util.concurrent.ConcurrentSkipListMap; import java.util.Iterator; import java.util.Locale; import java.util.Map; @@ -54,7 +55,8 @@ public abstract class FileSystemCounterGroup // C[] would need Array.newInstance which requires a Class reference. // Just a few local casts probably worth not having to carry it around. - private final Map map = Maps.newTreeMap(); + private final Map map = + new ConcurrentSkipListMap(); private String displayName; private static final Joiner NAME_JOINER = Joiner.on('_'); diff --git a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestCounters.java b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestCounters.java index f494556bac..74a4744e15 100644 --- a/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestCounters.java +++ b/hadoop-mapreduce-project/hadoop-mapreduce-client/hadoop-mapreduce-client-core/src/test/java/org/apache/hadoop/mapred/TestCounters.java @@ -18,6 +18,7 @@ package org.apache.hadoop.mapred; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; import java.io.IOException; import java.text.ParseException; @@ -203,6 +204,25 @@ public void testGroupIteratorConcurrency() { counters.incrCounter("group1", "counter2", 1); iterator.next(); } + + @Test + public void testFileSystemGroupIteratorConcurrency() { + Counters counters = new Counters(); + // create 2 filesystem counter groups + counters.findCounter("fs1", FileSystemCounter.BYTES_READ).increment(1); + counters.findCounter("fs2", FileSystemCounter.BYTES_READ).increment(1); + + // Iterate over the counters in this group while updating counters in + // the group + Group group = counters.getGroup(FileSystemCounter.class.getName()); + Iterator iterator = group.iterator(); + counters.findCounter("fs3", FileSystemCounter.BYTES_READ).increment(1); + assertTrue(iterator.hasNext()); + iterator.next(); + counters.findCounter("fs3", FileSystemCounter.BYTES_READ).increment(1); + assertTrue(iterator.hasNext()); + iterator.next(); + } public static void main(String[] args) throws IOException { new TestCounters().testCounters();