ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/jtreg/util/WeakHashMap/GCDuringIteration.java
Revision: 1.6
Committed: Mon May 25 19:06:26 2015 UTC (9 years ago) by jsr166
Branch: MAIN
Changes since 1.5: +1 -2 lines
Log Message:
unignore

File Contents

# Content
1 /*
2 * Copyright (c) 2007, 2011, 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 6499848
27 * @summary Check that iterators work properly in the presence of
28 * concurrent finalization and removal of elements.
29 * @key randomness
30 */
31
32 import java.util.*;
33 import java.util.concurrent.CountDownLatch;
34
35 public class GCDuringIteration {
36 private static void waitForFinalizersToRun() {
37 for (int i = 0; i < 2; i++)
38 tryWaitForFinalizersToRun();
39 }
40
41 private static void tryWaitForFinalizersToRun() {
42 System.gc();
43 final CountDownLatch fin = new CountDownLatch(1);
44 new Object() { protected void finalize() { fin.countDown(); }};
45 System.gc();
46 try { fin.await(); }
47 catch (InterruptedException ie) { throw new Error(ie); }
48 }
49
50 // A class with the traditional pessimal hashCode implementation,
51 // to ensure that all instances end up in the same bucket.
52 static class Foo { public int hashCode() { return 42; }}
53
54 <K,V> void put(Map<K,V> map, K k, V v) {
55 check(! map.containsKey(k));
56 equal(map.get(k), null);
57 equal(map.put(k, v), null);
58 equal(map.get(k), v);
59 check(map.containsKey(k));
60 equal(map.put(k, v), v);
61 equal(map.get(k), v);
62 check(map.containsKey(k));
63 check(! map.isEmpty());
64 equal(map.keySet().iterator().next(), k);
65 equal(map.values().iterator().next(), v);
66 }
67
68 void checkIterator(final Iterator<Map.Entry<Foo, Integer>> it, int first) {
69 final Random rnd = new Random();
70 for (int i = first; i >= 0; --i) {
71 if (rnd.nextBoolean()) check(it.hasNext());
72 equal(it.next().getValue(), i);
73 }
74 if (rnd.nextBoolean())
75 THROWS(NoSuchElementException.class,
76 new F(){void f(){it.next();}});
77 if (rnd.nextBoolean())
78 check(! it.hasNext());
79 }
80
81 <K,V> V firstValue(Map<K,V> map) {
82 return map.values().iterator().next();
83 }
84
85 void test(String[] args) throws Throwable {
86 final int n = 10;
87 // Create array of strong refs
88 final Foo[] foos = new Foo[2*n];
89 final Map<Foo,Integer> map = new WeakHashMap<Foo,Integer>(foos.length);
90 check(map.isEmpty());
91 equal(map.size(), 0);
92
93 for (int i = 0; i < foos.length; i++) {
94 Foo foo = new Foo();
95 foos[i] = foo;
96 put(map, foo, i);
97 }
98 equal(map.size(), foos.length);
99
100 {
101 int first = firstValue(map);
102 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
103 foos[first] = null;
104 for (int i = 0; i < 10 && map.size() != first; i++)
105 tryWaitForFinalizersToRun();
106 equal(map.size(), first);
107 checkIterator(it, first-1);
108 equal(map.size(), first);
109 equal(firstValue(map), first-1);
110 }
111
112 {
113 int first = firstValue(map);
114 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
115 it.next(); // protects first entry
116 System.out.println(map.values());
117 foos[first] = null;
118 tryWaitForFinalizersToRun();
119 equal(map.size(), first+1);
120 System.out.println(map.values());
121 checkIterator(it, first-1);
122 // first entry no longer protected
123 for (int i = 0; i < 10 && map.size() != first; i++)
124 tryWaitForFinalizersToRun();
125 equal(map.size(), first);
126 equal(firstValue(map), first-1);
127 }
128
129 {
130 int first = firstValue(map);
131 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
132 it.next(); // protects first entry
133 System.out.println(map.values());
134 foos[first] = foos[first-1] = null;
135 tryWaitForFinalizersToRun();
136 equal(map.size(), first);
137 equal(firstValue(map), first);
138 System.out.println(map.values());
139 checkIterator(it, first-2);
140 // first entry no longer protected
141 for (int i = 0; i < 10 && map.size() != first-1; i++)
142 tryWaitForFinalizersToRun();
143 equal(map.size(), first-1);
144 equal(firstValue(map), first-2);
145 }
146
147 {
148 int first = firstValue(map);
149 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
150 it.next(); // protects first entry
151 it.hasNext(); // protects second entry
152 System.out.println(map.values());
153 foos[first] = foos[first-1] = null;
154 tryWaitForFinalizersToRun();
155 equal(firstValue(map), first);
156 equal(map.size(), first+1);
157 System.out.println(map.values());
158 checkIterator(it, first-1);
159 // first entry no longer protected
160 for (int i = 0; i < 10 && map.size() != first-1; i++)
161 tryWaitForFinalizersToRun();
162 equal(map.size(), first-1);
163 equal(firstValue(map), first-2);
164 }
165
166 {
167 int first = firstValue(map);
168 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
169 it.next(); // protects first entry
170 System.out.println(map.values());
171 foos[first] = foos[first-1] = null;
172 tryWaitForFinalizersToRun();
173 it.remove();
174 equal(firstValue(map), first-2);
175 equal(map.size(), first-1);
176 System.out.println(map.values());
177 checkIterator(it, first-2);
178 // first entry no longer protected
179 for (int i = 0; i < 10 && map.size() != first-1; i++)
180 tryWaitForFinalizersToRun();
181 equal(map.size(), first-1);
182 equal(firstValue(map), first-2);
183 }
184
185 {
186 int first = firstValue(map);
187 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
188 it.next(); // protects first entry
189 it.remove();
190 it.hasNext(); // protects second entry
191 System.out.println(map.values());
192 foos[first] = foos[first-1] = null;
193 tryWaitForFinalizersToRun();
194 equal(firstValue(map), first-1);
195 equal(map.size(), first);
196 System.out.println(map.values());
197 checkIterator(it, first-1);
198 for (int i = 0; i < 10 && map.size() != first-1; i++)
199 tryWaitForFinalizersToRun();
200 equal(map.size(), first-1);
201 equal(firstValue(map), first-2);
202 }
203
204 {
205 int first = firstValue(map);
206 final Iterator<Map.Entry<Foo,Integer>> it = map.entrySet().iterator();
207 it.hasNext(); // protects first entry
208 Arrays.fill(foos, null);
209 tryWaitForFinalizersToRun();
210 equal(map.size(), 1);
211 System.out.println(map.values());
212 equal(it.next().getValue(), first);
213 check(! it.hasNext());
214 for (int i = 0; i < 10 && map.size() != 0; i++)
215 tryWaitForFinalizersToRun();
216 equal(map.size(), 0);
217 check(map.isEmpty());
218 }
219 }
220
221 //--------------------- Infrastructure ---------------------------
222 volatile int passed = 0, failed = 0;
223 void pass() {passed++;}
224 void fail() {failed++; Thread.dumpStack();}
225 void fail(String msg) {System.err.println(msg); fail();}
226 void unexpected(Throwable t) {failed++; t.printStackTrace();}
227 void check(boolean cond) {if (cond) pass(); else fail();}
228 void equal(Object x, Object y) {
229 if (x == null ? y == null : x.equals(y)) pass();
230 else fail(x + " not equal to " + y);}
231 public static void main(String[] args) throws Throwable {
232 new GCDuringIteration().instanceMain(args);}
233 void instanceMain(String[] args) throws Throwable {
234 try {test(args);} catch (Throwable t) {unexpected(t);}
235 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
236 if (failed > 0) throw new AssertionError("Some tests failed");}
237 abstract class F {abstract void f() throws Throwable;}
238 void THROWS(Class<? extends Throwable> k, F... fs) {
239 for (F f : fs)
240 try {f.f(); fail("Expected " + k.getName() + " not thrown");}
241 catch (Throwable t) {
242 if (k.isAssignableFrom(t.getClass())) pass();
243 else unexpected(t);}}
244 }