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 package test.java.util.Collection; 31 32 import java.lang.reflect.Constructor; 33 import java.util.ArrayList; 34 import java.util.Arrays; 35 import java.util.Collection; 36 import java.util.Collections; 37 import java.util.List; 38 import java.util.PriorityQueue; 39 import java.util.Vector; 40 import java.util.concurrent.CopyOnWriteArrayList; 41 import java.util.concurrent.PriorityBlockingQueue; 42 import org.testng.Assert; 43 import org.testng.annotations.Test; 44 45 @SuppressWarnings("unchecked") 46 public class HotPotatoes { 47 48 @Test testVector()49 public void testVector() throws Throwable { 50 testImplementation(Vector.class); 51 } 52 53 @Test testArrayList()54 public void testArrayList() throws Throwable { 55 testImplementation(ArrayList.class); 56 } 57 58 @Test testPriorityQueue()59 public void testPriorityQueue() throws Throwable { 60 testImplementation(PriorityQueue.class); 61 } 62 63 @Test testPriorityBlockingQueue()64 public void testPriorityBlockingQueue() throws Throwable { 65 testImplementation(PriorityBlockingQueue.class); 66 } 67 testImplementation(Class<? extends Collection> implClazz)68 private static void testImplementation(Class<? extends Collection> implClazz) throws Throwable { 69 testPotato(implClazz, Vector.class); 70 testPotato(implClazz, CopyOnWriteArrayList.class); 71 72 final Constructor<? extends Collection> constr 73 = implClazz.getConstructor(Collection.class); 74 final Collection<Object> coll 75 = constr.newInstance(Arrays.asList(new String[]{})); 76 coll.add(1); 77 Assert.assertEquals(coll.toString(), "[1]"); 78 } 79 testPotato(Class<? extends Collection> implClazz, Class<? extends List> argClazz)80 private static void testPotato(Class<? extends Collection> implClazz, 81 Class<? extends List> argClazz) throws Throwable { 82 try { 83 System.out.printf("implClazz=%s, argClazz=%s\n", 84 implClazz.getName(), argClazz.getName()); 85 final int iterations = 100000; 86 final List<Integer> list = (List<Integer>) 87 argClazz.getDeclaredConstructor().newInstance(); 88 final Integer one = Integer.valueOf(1); 89 final List<Integer> oneElementList = Collections.singletonList(one); 90 final Constructor<? extends Collection> constr 91 = implClazz.getConstructor(Collection.class); 92 final Thread t = new CheckedThread() { 93 public void realRun() { 94 for (int i = 0; i < iterations; i++) { 95 list.add(one); 96 list.remove(one); 97 } 98 } 99 }; 100 t.setDaemon(true); 101 t.start(); 102 103 for (int i = 0; i < iterations; i++) { 104 Collection<?> coll = constr.newInstance(list); 105 Object[] elts = coll.toArray(); 106 Assert.assertTrue(elts.length == 0 || (elts.length == 1 && elts[0] == one)); 107 } 108 } catch (Throwable t) { 109 Assert.fail("Unexpected exception: " + t.getMessage()); 110 } 111 } 112 113 private abstract static class CheckedThread extends Thread { 114 realRun()115 public abstract void realRun() throws Throwable; 116 run()117 public void run() { 118 try { 119 realRun(); 120 } catch (Throwable t) { 121 Assert.fail("Unexpected exception: " + t.getMessage()); 122 } 123 } 124 } 125 } 126