1
2
3
4
5
6
7
8
9
10
11
12
13
14 package com.google.common.util.concurrent;
15
16 import junit.framework.*;
17
18 import java.util.Arrays;
19
20
21
22
23 public class AtomicDoubleArrayTest extends JSR166TestCase {
24
25 private static final double[] VALUES = {
26 Double.NEGATIVE_INFINITY,
27 -Double.MAX_VALUE,
28 (double) Long.MIN_VALUE,
29 (double) Integer.MIN_VALUE,
30 -Math.PI,
31 -1.0,
32 -Double.MIN_VALUE,
33 -0.0,
34 +0.0,
35 Double.MIN_VALUE,
36 1.0,
37 Math.PI,
38 (double) Integer.MAX_VALUE,
39 (double) Long.MAX_VALUE,
40 Double.MAX_VALUE,
41 Double.POSITIVE_INFINITY,
42 Double.NaN,
43 Float.MAX_VALUE,
44 };
45
46
47 static boolean bitEquals(double x, double y) {
48 return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y);
49 }
50
51 static void assertBitEquals(double x, double y) {
52 assertEquals(Double.doubleToRawLongBits(x),
53 Double.doubleToRawLongBits(y));
54 }
55
56
57
58
59 public void testConstructor() {
60 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
61 for (int i = 0; i < SIZE; i++) {
62 assertBitEquals(0.0, aa.get(i));
63 }
64 }
65
66
67
68
69 public void testConstructor2NPE() {
70 try {
71 double[] a = null;
72 AtomicDoubleArray aa = new AtomicDoubleArray(a);
73 shouldThrow();
74 } catch (NullPointerException success) {}
75 }
76
77
78
79
80 public void testConstructor2() {
81 AtomicDoubleArray aa = new AtomicDoubleArray(VALUES);
82 assertEquals(VALUES.length, aa.length());
83 for (int i = 0; i < VALUES.length; i++) {
84 assertBitEquals(VALUES[i], aa.get(i));
85 }
86 }
87
88
89
90
91 public void testConstructorEmptyArray() {
92 AtomicDoubleArray aa = new AtomicDoubleArray(new double[0]);
93 assertEquals(0, aa.length());
94 try {
95 aa.get(0);
96 shouldThrow();
97 } catch (IndexOutOfBoundsException success) {}
98 }
99
100
101
102
103 public void testConstructorZeroLength() {
104 AtomicDoubleArray aa = new AtomicDoubleArray(0);
105 assertEquals(0, aa.length());
106 try {
107 aa.get(0);
108 shouldThrow();
109 } catch (IndexOutOfBoundsException success) {}
110 }
111
112
113
114
115 public void testIndexing() {
116 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
117 for (int index : new int[] { -1, SIZE }) {
118 try {
119 aa.get(index);
120 shouldThrow();
121 } catch (IndexOutOfBoundsException success) {}
122 try {
123 aa.set(index, 1.0);
124 shouldThrow();
125 } catch (IndexOutOfBoundsException success) {}
126 try {
127 aa.lazySet(index, 1.0);
128 shouldThrow();
129 } catch (IndexOutOfBoundsException success) {}
130 try {
131 aa.compareAndSet(index, 1.0, 2.0);
132 shouldThrow();
133 } catch (IndexOutOfBoundsException success) {}
134 try {
135 aa.weakCompareAndSet(index, 1.0, 2.0);
136 shouldThrow();
137 } catch (IndexOutOfBoundsException success) {}
138 try {
139 aa.getAndAdd(index, 1.0);
140 shouldThrow();
141 } catch (IndexOutOfBoundsException success) {}
142 try {
143 aa.addAndGet(index, 1.0);
144 shouldThrow();
145 } catch (IndexOutOfBoundsException success) {}
146 }
147 }
148
149
150
151
152 public void testGetSet() {
153 AtomicDoubleArray aa = new AtomicDoubleArray(VALUES.length);
154 for (int i = 0; i < VALUES.length; i++) {
155 assertBitEquals(0.0, aa.get(i));
156 aa.set(i, VALUES[i]);
157 assertBitEquals(VALUES[i], aa.get(i));
158 aa.set(i, -3.0);
159 assertBitEquals(-3.0, aa.get(i));
160 }
161 }
162
163
164
165
166 public void testGetLazySet() {
167 AtomicDoubleArray aa = new AtomicDoubleArray(VALUES.length);
168 for (int i = 0; i < VALUES.length; i++) {
169 assertBitEquals(0.0, aa.get(i));
170 aa.lazySet(i, VALUES[i]);
171 assertBitEquals(VALUES[i], aa.get(i));
172 aa.lazySet(i, -3.0);
173 assertBitEquals(-3.0, aa.get(i));
174 }
175 }
176
177
178
179
180 public void testCompareAndSet() {
181 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
182 for (int i : new int[] { 0, SIZE - 1}) {
183 double prev = 0.0;
184 double unused = Math.E + Math.PI;
185 for (double x : VALUES) {
186 assertBitEquals(prev, aa.get(i));
187 assertFalse(aa.compareAndSet(i, unused, x));
188 assertBitEquals(prev, aa.get(i));
189 assertTrue(aa.compareAndSet(i, prev, x));
190 assertBitEquals(x, aa.get(i));
191 prev = x;
192 }
193 }
194 }
195
196
197
198
199
200
201 public void testCompareAndSetInMultipleThreads() throws InterruptedException {
202 final AtomicDoubleArray a = new AtomicDoubleArray(1);
203 a.set(0, 1.0);
204 Thread t = newStartedThread(new CheckedRunnable() {
205 public void realRun() {
206 while (!a.compareAndSet(0, 2.0, 3.0)) {
207 Thread.yield();
208 }
209 }});
210
211 assertTrue(a.compareAndSet(0, 1.0, 2.0));
212 awaitTermination(t);
213 assertBitEquals(3.0, a.get(0));
214 }
215
216
217
218
219
220 public void testWeakCompareAndSet() {
221 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
222 for (int i : new int[] { 0, SIZE - 1}) {
223 double prev = 0.0;
224 double unused = Math.E + Math.PI;
225 for (double x : VALUES) {
226 assertBitEquals(prev, aa.get(i));
227 assertFalse(aa.weakCompareAndSet(i, unused, x));
228 assertBitEquals(prev, aa.get(i));
229 while (!aa.weakCompareAndSet(i, prev, x)) {
230 ;
231 }
232 assertBitEquals(x, aa.get(i));
233 prev = x;
234 }
235 }
236 }
237
238
239
240
241 public void testGetAndSet() {
242 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
243 for (int i : new int[] { 0, SIZE - 1}) {
244 double prev = 0.0;
245 for (double x : VALUES) {
246 assertBitEquals(prev, aa.getAndSet(i, x));
247 prev = x;
248 }
249 }
250 }
251
252
253
254
255 public void testGetAndAdd() {
256 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
257 for (int i : new int[] { 0, SIZE - 1}) {
258 for (double x : VALUES) {
259 for (double y : VALUES) {
260 aa.set(i, x);
261 double z = aa.getAndAdd(i, y);
262 assertBitEquals(x, z);
263 assertBitEquals(x + y, aa.get(i));
264 }
265 }
266 }
267 }
268
269
270
271
272 public void testAddAndGet() {
273 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
274 for (int i : new int[] { 0, SIZE - 1}) {
275 for (double x : VALUES) {
276 for (double y : VALUES) {
277 aa.set(i, x);
278 double z = aa.addAndGet(i, y);
279 assertBitEquals(x + y, z);
280 assertBitEquals(x + y, aa.get(i));
281 }
282 }
283 }
284 }
285
286 static final long COUNTDOWN = 100000;
287
288 class Counter extends CheckedRunnable {
289 final AtomicDoubleArray aa;
290 volatile long counts;
291 Counter(AtomicDoubleArray a) { aa = a; }
292 public void realRun() {
293 for (;;) {
294 boolean done = true;
295 for (int i = 0; i < aa.length(); i++) {
296 double v = aa.get(i);
297 assertTrue(v >= 0);
298 if (v != 0) {
299 done = false;
300 if (aa.compareAndSet(i, v, v - 1.0)) {
301 ++counts;
302 }
303 }
304 }
305 if (done) {
306 break;
307 }
308 }
309 }
310 }
311
312
313
314
315
316
317 public void testCountingInMultipleThreads() throws InterruptedException {
318 final AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
319 for (int i = 0; i < SIZE; i++) {
320 aa.set(i, (double) COUNTDOWN);
321 }
322 Counter c1 = new Counter(aa);
323 Counter c2 = new Counter(aa);
324 Thread t1 = newStartedThread(c1);
325 Thread t2 = newStartedThread(c2);
326 awaitTermination(t1);
327 awaitTermination(t2);
328 assertEquals(c1.counts + c2.counts, SIZE * COUNTDOWN);
329 }
330
331
332
333
334 public void testSerialization() throws Exception {
335 AtomicDoubleArray x = new AtomicDoubleArray(SIZE);
336 for (int i = 0; i < SIZE; i++) {
337 x.set(i, (double) -i);
338 }
339 AtomicDoubleArray y = serialClone(x);
340 assertTrue(x != y);
341 assertEquals(x.length(), y.length());
342 for (int i = 0; i < SIZE; i++) {
343 assertBitEquals(x.get(i), y.get(i));
344 }
345
346 AtomicDoubleArray a = new AtomicDoubleArray(VALUES);
347 AtomicDoubleArray b = serialClone(a);
348 assertFalse(a.equals(b));
349 assertFalse(b.equals(a));
350 assertEquals(a.length(), b.length());
351 for (int i = 0; i < VALUES.length; i++) {
352 assertBitEquals(a.get(i), b.get(i));
353 }
354 }
355
356
357
358
359 public void testToString() {
360 AtomicDoubleArray aa = new AtomicDoubleArray(VALUES);
361 assertEquals(Arrays.toString(VALUES), aa.toString());
362 assertEquals("[]", new AtomicDoubleArray(0).toString());
363 assertEquals("[]", new AtomicDoubleArray(new double[0]).toString());
364 }
365
366
367
368
369 public void testDistinctZeros() {
370 AtomicDoubleArray aa = new AtomicDoubleArray(SIZE);
371 for (int i : new int[] { 0, SIZE - 1}) {
372 assertFalse(aa.compareAndSet(i, -0.0, 7.0));
373 assertFalse(aa.weakCompareAndSet(i, -0.0, 7.0));
374 assertBitEquals(+0.0, aa.get(i));
375 assertTrue(aa.compareAndSet(i, +0.0, -0.0));
376 assertBitEquals(-0.0, aa.get(i));
377 assertFalse(aa.compareAndSet(i, +0.0, 7.0));
378 assertFalse(aa.weakCompareAndSet(i, +0.0, 7.0));
379 assertBitEquals(-0.0, aa.get(i));
380 }
381 }
382 }