1 /*
2  * Written by Doug Lea with assistance from members of JCP JSR-166
3  * Expert Group and released to the public domain, as explained at
4  * http://creativecommons.org/publicdomain/zero/1.0/
5  * Other contributors include Andrew Wright, Jeffrey Hayes,
6  * Pat Fisher, Mike Judd.
7  */
8 
9 package jsr166;
10 
11 import junit.framework.*;
12 import java.util.Arrays;
13 import java.util.concurrent.atomic.AtomicReferenceArray;
14 
15 public class AtomicReferenceArrayTest extends JSR166TestCase {
16 
17     /**
18      * constructor creates array of given size with all elements null
19      */
testConstructor()20     public void testConstructor() {
21         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
22         for (int i = 0; i < SIZE; i++) {
23             assertNull(aa.get(i));
24         }
25     }
26 
27     /**
28      * constructor with null array throws NPE
29      */
testConstructor2NPE()30     public void testConstructor2NPE() {
31         try {
32             Integer[] a = null;
33             AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
34             shouldThrow();
35         } catch (NullPointerException success) {}
36     }
37 
38     /**
39      * constructor with array is of same size and has all elements
40      */
testConstructor2()41     public void testConstructor2() {
42         Integer[] a = { two, one, three, four, seven };
43         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
44         assertEquals(a.length, aa.length());
45         for (int i = 0; i < a.length; i++)
46             assertEquals(a[i], aa.get(i));
47     }
48 
49     /**
50      * Initialize AtomicReferenceArray<Class> with SubClass[]
51      */
testConstructorSubClassArray()52     public void testConstructorSubClassArray() {
53         Integer[] a = { two, one, three, four, seven };
54         AtomicReferenceArray<Number> aa = new AtomicReferenceArray<Number>(a);
55         assertEquals(a.length, aa.length());
56         for (int i = 0; i < a.length; i++) {
57             assertSame(a[i], aa.get(i));
58             Long x = Long.valueOf(i);
59             aa.set(i, x);
60             assertSame(x, aa.get(i));
61         }
62     }
63 
64     /**
65      * get and set for out of bound indices throw IndexOutOfBoundsException
66      */
testIndexing()67     public void testIndexing() {
68         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(SIZE);
69         for (int index : new int[] { -1, SIZE }) {
70             try {
71                 aa.get(index);
72                 shouldThrow();
73             } catch (IndexOutOfBoundsException success) {}
74             try {
75                 aa.set(index, null);
76                 shouldThrow();
77             } catch (IndexOutOfBoundsException success) {}
78             try {
79                 aa.lazySet(index, null);
80                 shouldThrow();
81             } catch (IndexOutOfBoundsException success) {}
82             try {
83                 aa.compareAndSet(index, null, null);
84                 shouldThrow();
85             } catch (IndexOutOfBoundsException success) {}
86             try {
87                 aa.weakCompareAndSet(index, null, null);
88                 shouldThrow();
89             } catch (IndexOutOfBoundsException success) {}
90         }
91     }
92 
93     /**
94      * get returns the last value set at index
95      */
testGetSet()96     public void testGetSet() {
97         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
98         for (int i = 0; i < SIZE; i++) {
99             aa.set(i, one);
100             assertSame(one, aa.get(i));
101             aa.set(i, two);
102             assertSame(two, aa.get(i));
103             aa.set(i, m3);
104             assertSame(m3, aa.get(i));
105         }
106     }
107 
108     /**
109      * get returns the last value lazySet at index by same thread
110      */
testGetLazySet()111     public void testGetLazySet() {
112         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
113         for (int i = 0; i < SIZE; i++) {
114             aa.lazySet(i, one);
115             assertSame(one, aa.get(i));
116             aa.lazySet(i, two);
117             assertSame(two, aa.get(i));
118             aa.lazySet(i, m3);
119             assertSame(m3, aa.get(i));
120         }
121     }
122 
123     /**
124      * compareAndSet succeeds in changing value if equal to expected else fails
125      */
testCompareAndSet()126     public void testCompareAndSet() {
127         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
128         for (int i = 0; i < SIZE; i++) {
129             aa.set(i, one);
130             assertTrue(aa.compareAndSet(i, one, two));
131             assertTrue(aa.compareAndSet(i, two, m4));
132             assertSame(m4, aa.get(i));
133             assertFalse(aa.compareAndSet(i, m5, seven));
134             assertSame(m4, aa.get(i));
135             assertTrue(aa.compareAndSet(i, m4, seven));
136             assertSame(seven, aa.get(i));
137         }
138     }
139 
140     /**
141      * compareAndSet in one thread enables another waiting for value
142      * to succeed
143      */
testCompareAndSetInMultipleThreads()144     public void testCompareAndSetInMultipleThreads() throws InterruptedException {
145         final AtomicReferenceArray a = new AtomicReferenceArray(1);
146         a.set(0, one);
147         Thread t = new Thread(new CheckedRunnable() {
148             public void realRun() {
149                 while (!a.compareAndSet(0, two, three))
150                     Thread.yield();
151             }});
152 
153         t.start();
154         assertTrue(a.compareAndSet(0, one, two));
155         t.join(LONG_DELAY_MS);
156         assertFalse(t.isAlive());
157         assertSame(three, a.get(0));
158     }
159 
160     /**
161      * repeated weakCompareAndSet succeeds in changing value when equal
162      * to expected
163      */
testWeakCompareAndSet()164     public void testWeakCompareAndSet() {
165         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
166         for (int i = 0; i < SIZE; i++) {
167             aa.set(i, one);
168             while (!aa.weakCompareAndSet(i, one, two));
169             while (!aa.weakCompareAndSet(i, two, m4));
170             assertSame(m4, aa.get(i));
171             while (!aa.weakCompareAndSet(i, m4, seven));
172             assertSame(seven, aa.get(i));
173         }
174     }
175 
176     /**
177      * getAndSet returns previous value and sets to given value at given index
178      */
testGetAndSet()179     public void testGetAndSet() {
180         AtomicReferenceArray aa = new AtomicReferenceArray(SIZE);
181         for (int i = 0; i < SIZE; i++) {
182             aa.set(i, one);
183             assertSame(one, aa.getAndSet(i, zero));
184             assertSame(zero, aa.getAndSet(i, m10));
185             assertSame(m10, aa.getAndSet(i, one));
186         }
187     }
188 
189     /**
190      * a deserialized serialized array holds same values
191      */
testSerialization()192     public void testSerialization() throws Exception {
193         AtomicReferenceArray x = new AtomicReferenceArray(SIZE);
194         for (int i = 0; i < SIZE; i++) {
195             x.set(i, new Integer(-i));
196         }
197         AtomicReferenceArray y = serialClone(x);
198         assertNotSame(x, y);
199         assertEquals(x.length(), y.length());
200         for (int i = 0; i < SIZE; i++) {
201             assertEquals(x.get(i), y.get(i));
202         }
203     }
204 
205     /**
206      * toString returns current value.
207      */
testToString()208     public void testToString() {
209         Integer[] a = { two, one, three, four, seven };
210         AtomicReferenceArray<Integer> aa = new AtomicReferenceArray<Integer>(a);
211         assertEquals(Arrays.toString(a), aa.toString());
212     }
213 }
214