--- jsr166/src/test/tck/ConcurrentHashMap8Test.java 2015/02/27 19:47:57 1.23 +++ jsr166/src/test/tck/ConcurrentHashMap8Test.java 2018/05/28 21:36:41 1.37 @@ -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); @@ -62,7 +63,7 @@ public class ConcurrentHashMap8Test exte */ public void testComputeIfAbsent() { ConcurrentHashMap map = map5(); - map.computeIfAbsent(six, (x) -> "Z"); + map.computeIfAbsent(six, x -> "Z"); assertTrue(map.containsKey(six)); } @@ -71,7 +72,7 @@ public class ConcurrentHashMap8Test exte */ public void testComputeIfAbsent2() { ConcurrentHashMap map = map5(); - assertEquals("A", map.computeIfAbsent(one, (x) -> "Z")); + assertEquals("A", map.computeIfAbsent(one, x -> "Z")); } /** @@ -79,7 +80,7 @@ public class ConcurrentHashMap8Test exte */ public void testComputeIfAbsent3() { ConcurrentHashMap map = map5(); - map.computeIfAbsent(six, (x) -> null); + map.computeIfAbsent(six, x -> null); assertFalse(map.containsKey(six)); } @@ -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; @@ -172,8 +173,8 @@ public class ConcurrentHashMap8Test exte static Set populatedSet(Integer[] elements) { Set a = ConcurrentHashMap.newKeySet(); assertTrue(a.isEmpty()); - for (int i = 0; i < elements.length; i++) - a.add(elements[i]); + for (Integer element : elements) + assertTrue(a.add(element)); assertFalse(a.isEmpty()); assertEquals(elements.length, a.size()); return a; @@ -184,7 +185,7 @@ public class ConcurrentHashMap8Test exte */ public void testReplaceAll() { ConcurrentHashMap map = map5(); - map.replaceAll((x, y) -> { return x > 3 ? "Z" : y; }); + map.replaceAll((x, y) -> (x > 3) ? "Z" : y); assertEquals("A", map.get(one)); assertEquals("B", map.get(two)); assertEquals("C", map.get(three)); @@ -209,8 +210,8 @@ public class ConcurrentHashMap8Test exte Set set1 = map.keySet(); Set set2 = map.keySet(true); set2.add(six); - assertTrue(((ConcurrentHashMap.KeySetView)set2).getMap() == map); - assertTrue(((ConcurrentHashMap.KeySetView)set1).getMap() == map); + assertSame(map, ((ConcurrentHashMap.KeySetView)set2).getMap()); + assertSame(map, ((ConcurrentHashMap.KeySetView)set1).getMap()); assertEquals(set2.size(), map.size()); assertEquals(set1.size(), map.size()); assertTrue((Boolean)map.get(six)); @@ -251,7 +252,7 @@ public class ConcurrentHashMap8Test exte */ public void testAdd2() { Set full = populatedSet(3); - full.add(one); + assertFalse(full.add(one)); assertEquals(3, full.size()); } @@ -260,7 +261,9 @@ public class ConcurrentHashMap8Test exte */ public void testAdd3() { Set full = populatedSet(3); - full.add(three); + assertTrue(full.add(three)); + assertTrue(full.contains(three)); + assertFalse(full.add(three)); assertTrue(full.contains(three)); } @@ -273,7 +276,7 @@ public class ConcurrentHashMap8Test exte try { full.add(three); shouldThrow(); - } catch (UnsupportedOperationException e){} + } catch (UnsupportedOperationException success) {} } /** @@ -285,7 +288,7 @@ public class ConcurrentHashMap8Test exte try { full.add(null); shouldThrow(); - } catch (NullPointerException e){} + } catch (NullPointerException success) {} } /** @@ -297,15 +300,15 @@ public class ConcurrentHashMap8Test exte try { map.keySet(null); shouldThrow(); - } catch (NullPointerException e) {} + } catch (NullPointerException success) {} ConcurrentHashMap.KeySetView set = map.keySet(one); - set.add(one); - set.add(six); - set.add(seven); - assertTrue(set.getMappedValue() == one); - assertTrue(map.get(one) != one); - assertTrue(map.get(six) == one); - assertTrue(map.get(seven) == one); + assertFalse(set.add(one)); + assertTrue(set.add(six)); + assertTrue(set.add(seven)); + assertSame(one, set.getMappedValue()); + assertNotSame(one, map.get(one)); + assertSame(one, map.get(six)); + assertSame(one, map.get(seven)); } void checkSpliteratorCharacteristics(Spliterator sp, @@ -404,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(); @@ -494,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()))); @@ -514,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]); @@ -524,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); @@ -540,7 +543,7 @@ public class ConcurrentHashMap8Test exte } /** - * A deserialized serialized set is equal + * A deserialized/reserialized set equals original */ public void testSerialization() throws Exception { int size = 20; @@ -1086,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); + } + } + }