--- jsr166/src/test/tck/ConcurrentHashMap8Test.java 2015/02/27 21:43:18 1.26 +++ jsr166/src/test/tck/ConcurrentHashMap8Test.java 2016/10/15 18:51:12 1.32 @@ -11,12 +11,13 @@ import static java.util.Spliterator.NONN import java.util.AbstractMap; import java.util.Arrays; import java.util.Collection; -import java.util.Collections; import java.util.Iterator; import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; import java.util.Spliterator; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.LongAdder; import java.util.function.BiFunction; @@ -26,7 +27,7 @@ import junit.framework.TestSuite; public class ConcurrentHashMap8Test extends JSR166TestCase { public static void main(String[] args) { - junit.textui.TestRunner.run(suite()); + main(suite(), args); } public static Test suite() { return new TestSuite(ConcurrentHashMap8Test.class); @@ -163,7 +164,7 @@ public class ConcurrentHashMap8Test exte Set a = ConcurrentHashMap.newKeySet(); assertTrue(a.isEmpty()); for (int i = 0; i < n; i++) - a.add(i); + assertTrue(a.add(i)); assertEquals(n == 0, a.isEmpty()); assertEquals(n, a.size()); return a; @@ -173,7 +174,7 @@ public class ConcurrentHashMap8Test exte Set a = ConcurrentHashMap.newKeySet(); assertTrue(a.isEmpty()); for (int i = 0; i < elements.length; i++) - a.add(elements[i]); + assertTrue(a.add(elements[i])); assertFalse(a.isEmpty()); assertEquals(elements.length, a.size()); return a; @@ -301,9 +302,9 @@ public class ConcurrentHashMap8Test exte shouldThrow(); } catch (NullPointerException success) {} ConcurrentHashMap.KeySetView set = map.keySet(one); - set.add(one); - set.add(six); - set.add(seven); + assertFalse(set.add(one)); + assertTrue(set.add(six)); + assertTrue(set.add(seven)); assertTrue(set.getMappedValue() == one); assertTrue(map.get(one) != one); assertTrue(map.get(six) == one); @@ -406,7 +407,7 @@ public class ConcurrentHashMap8Test exte Integer[] elements = new Integer[size]; for (int i = 0; i < size; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedSet(elements); Iterator it = full.iterator(); @@ -496,7 +497,7 @@ public class ConcurrentHashMap8Test exte Integer[] elements = new Integer[size]; for (int i = 0; i < size; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedSet(elements); assertTrue(Arrays.asList(elements).containsAll(Arrays.asList(full.toArray()))); @@ -516,7 +517,7 @@ public class ConcurrentHashMap8Test exte a = new Integer[0]; assertSame(a, empty.toArray(a)); - a = new Integer[size/2]; + a = new Integer[size / 2]; Arrays.fill(a, 42); assertSame(a, empty.toArray(a)); assertNull(a[0]); @@ -526,7 +527,7 @@ public class ConcurrentHashMap8Test exte Integer[] elements = new Integer[size]; for (int i = 0; i < size; i++) elements[i] = i; - Collections.shuffle(Arrays.asList(elements)); + shuffle(elements); Collection full = populatedSet(elements); Arrays.fill(a, 42); @@ -1088,4 +1089,30 @@ public class ConcurrentHashMap8Test exte assertNull(r); } + /** + * Tests performance of computeIfAbsent when the element is present. + * See JDK-8161372 + * ant -Djsr166.tckTestClass=ConcurrentHashMapTest -Djsr166.methodFilter=testcomputeIfAbsent_performance -Djsr166.expensiveTests=true tck + */ + public void testcomputeIfAbsent_performance() { + final int mapSize = 20; + final int iterations = expensiveTests ? (1 << 23) : mapSize * 2; + final int threads = expensiveTests ? 10 : 2; + final ConcurrentHashMap map = new ConcurrentHashMap<>(); + for (int i = 0; i < mapSize; i++) + map.put(i, i); + final ExecutorService pool = Executors.newFixedThreadPool(2); + try (PoolCleaner cleaner = cleaner(pool)) { + Runnable r = new CheckedRunnable() { + public void realRun() { + int result = 0; + for (int i = 0; i < iterations; i++) + result += map.computeIfAbsent(i % mapSize, (k) -> k + k); + if (result == -42) throw new Error(); + }}; + for (int i = 0; i < threads; i++) + pool.execute(r); + } + } + }