1 /*
2 * Copyright (c) 2005, 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 6330307 6355645
27 * @summary Check for race conditions in COWArray classes
28 * @author Martin Buchholz
29 */
30
31 import java.util.*;
32 import java.util.concurrent.*;
33
34 public class RacingCows {
35 private static void realMain(String[] args) throws Throwable {
36 final int iterations = 100000;
37 final Integer two = Integer.valueOf(2);
38 final Integer three = Integer.valueOf(3);
39
40 //------------ CopyOnWriteArraySet -------------------------------
41 final Set<Integer> s1 = new CopyOnWriteArraySet<Integer>();
42 final Set<Integer> s2 = new CopyOnWriteArraySet<Integer>();
43 s1.add(1);
44
45 final Thread t1 = new CheckedThread() { public void realRun() {
46 for (int i = 0; i < iterations; i++) {
47 s2.add(two);
48 s2.remove(two);
49 }}};
50 t1.start();
51
52 for (int i = 0; i < iterations; i++) {
53 check(! s1.equals(s2));
54 check(! s2.equals(s1));
55 }
56 t1.join();
57
58 //------------ CopyOnWriteArrayList ------------------------------
59 final List<Integer> l1 = new CopyOnWriteArrayList<Integer>();
60 final List<Integer> l2 = new CopyOnWriteArrayList<Integer>();
61 final List<Integer> l3 = new CopyOnWriteArrayList<Integer>();
62 l1.add(1);
63
64 final Thread t2 = new CheckedThread() { public void realRun() {
65 for (int i = 0; i < iterations; i++) {
66 switch (i%2) {
67 case 0: l2.add(two); break;
68 case 1: l2.add(0, two); break;
69 }
70 switch (i%3) {
71 case 0: l2.remove(two); break;
72 case 1: l2.remove(0); break;
73 case 2: l2.clear(); break;
74 }}}};
75 t2.start();
76
77 final Thread t3 = new CheckedThread() { public void realRun() {
78 l3.add(three);
79 for (int i = 0; i < iterations; i++) {
80 switch (i%2) {
81 case 0: l3.add(two); break;
82 case 1: l3.add(0, two); break;
83 }
84 switch (i%2) {
85 case 0: l3.remove(two); break;
86 case 1: l3.remove(0); break;
87 }}}};
88 t3.start();
89
90 for (int i = 0; i < iterations; i++) {
91 check(! l1.equals(l2));
92 check(! l2.equals(l1));
93
94 // CopyOnWriteArrayList(mutatingCollection)
95 try { new CopyOnWriteArrayList<Integer>(l2); }
96 catch (Throwable t) { unexpected(t); }
97
98 // addAllAbsent(mutatingCollection)
99 try { new CopyOnWriteArrayList<Integer>().addAllAbsent(l3); }
100 catch (Throwable t) { unexpected(t); }
101
102 // addAll(mutatingCollection)
103 try { new CopyOnWriteArrayList<Integer>().addAll(l3); }
104 catch (Throwable t) { unexpected(t); }
105
106 // addAll(int, mutatingCollection)
107 try { new CopyOnWriteArrayList<Integer>().addAll(0,l3); }
108 catch (Throwable t) { unexpected(t); }
109 }
110 t2.join();
111 t3.join();
112 }
113
114 //--------------------- Infrastructure ---------------------------
115 static volatile int passed = 0, failed = 0;
116 static void pass() {passed++;}
117 static void fail() {failed++; Thread.dumpStack();}
118 static void fail(String msg) {System.out.println(msg); fail();}
119 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
120 static void check(boolean cond) {if (cond) pass(); else fail();}
121 static void equal(Object x, Object y) {
122 if (x == null ? y == null : x.equals(y)) pass();
123 else fail(x + " not equal to " + y);}
124 public static void main(String[] args) throws Throwable {
125 try {realMain(args);} catch (Throwable t) {unexpected(t);}
126 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
127 if (failed > 0) throw new AssertionError("Some tests failed");}
128 private static abstract class CheckedThread extends Thread {
129 public abstract void realRun() throws Throwable;
130 public void run() {
131 try { realRun(); } catch (Throwable t) { unexpected(t); }}}
132 }
--- EOF ---