HotPotatoes.java revision 12745:f068a4ffddd2
1/* 2 * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24/* 25 * @test 26 * @bug 6355660 6347106 6394004 27 * @summary methods taking concurrently mutating collection should work 28 * @author Martin Buchholz 29 */ 30 31import java.lang.reflect.*; 32import java.util.*; 33import java.util.concurrent.*; 34 35@SuppressWarnings("unchecked") 36public class HotPotatoes { 37 private static void realMain(String[] args) throws Throwable { 38 testImplementation(Vector.class); 39 testImplementation(ArrayList.class); 40 testImplementation(PriorityQueue.class); 41 testImplementation(PriorityBlockingQueue.class); 42 } 43 44 private static void testImplementation(Class<? extends Collection> implClazz) 45 throws Throwable 46 { 47 testPotato(implClazz, Vector.class); 48 testPotato(implClazz, CopyOnWriteArrayList.class); 49 50 final Constructor<? extends Collection> constr 51 = implClazz.getConstructor(Collection.class); 52 final Collection<Object> coll 53 = constr.newInstance(Arrays.asList(new String[] {})); 54 coll.add(1); 55 equal(coll.toString(), "[1]"); 56 } 57 58 private static void testPotato(Class<? extends Collection> implClazz, 59 Class<? extends List> argClazz) 60 throws Throwable 61 { 62 try { 63 System.out.printf("implClazz=%s, argClazz=%s\n", 64 implClazz.getName(), argClazz.getName()); 65 final int iterations = 100000; 66 final List<Integer> list = (List<Integer>) argClazz.newInstance(); 67 final Integer one = Integer.valueOf(1); 68 final List<Integer> oneElementList = Collections.singletonList(one); 69 final Constructor<? extends Collection> constr 70 = implClazz.getConstructor(Collection.class); 71 final Thread t = new CheckedThread() { public void realRun() { 72 for (int i = 0; i < iterations; i++) { 73 list.add(one); 74 list.remove(one); 75 }}}; 76 t.setDaemon(true); 77 t.start(); 78 79 for (int i = 0; i < iterations; i++) { 80 Collection<?> coll = constr.newInstance(list); 81 Object[] elts = coll.toArray(); 82 check(elts.length == 0 || 83 (elts.length == 1 && elts[0] == one)); 84 } 85 } catch (Throwable t) { unexpected(t); } 86 } 87 88 //--------------------- Infrastructure --------------------------- 89 static volatile int passed = 0, failed = 0; 90 static void pass() {passed++;} 91 static void fail() {failed++; Thread.dumpStack();} 92 static void fail(String msg) {System.out.println(msg); fail();} 93 static void unexpected(Throwable t) {failed++; t.printStackTrace();} 94 static void check(boolean cond) {if (cond) pass(); else fail();} 95 static void equal(Object x, Object y) { 96 if (x == null ? y == null : x.equals(y)) pass(); 97 else fail(x + " not equal to " + y);} 98 public static void main(String[] args) throws Throwable { 99 try {realMain(args);} catch (Throwable t) {unexpected(t);} 100 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); 101 if (failed > 0) throw new AssertionError("Some tests failed");} 102 private abstract static class CheckedThread extends Thread { 103 public abstract void realRun() throws Throwable; 104 public void run() { 105 try { realRun(); } catch (Throwable t) { unexpected(t); }}} 106} 107