blob: 818a3b2d8834731b7641b526c432f57c957eee34 [file] [log] [blame]
Calin Juravle8f0d92b2013-08-01 17:26:00 +01001/*
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
9package jsr166;
10
Calin Juravle8f0d92b2013-08-01 17:26:00 +010011import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
12
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010013import junit.framework.Test;
14import junit.framework.TestSuite;
15
Calin Juravle8f0d92b2013-08-01 17:26:00 +010016public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase {
17 volatile int x = 0;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000018 protected volatile int protectedField;
19 private volatile int privateField;
Calin Juravle8f0d92b2013-08-01 17:26:00 +010020 int w;
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000021 float z;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010022 // android-note: Removed because the CTS runner does a bad job of
23 // retrying tests that have suite() declarations.
24 //
25 // public static void main(String[] args) {
26 // main(suite(), args);
27 // }
28 // public static Test suite() {
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000029 // return new TestSuite(AtomicIntegerFieldUpdaterTest.class);
30 // }
31
32 // for testing subclass access
Pete Gillinfbdae2c2018-03-20 14:55:37 +000033 static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest {
34 public void checkPrivateAccess() {
35 try {
36 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
37 AtomicIntegerFieldUpdater.newUpdater
38 (AtomicIntegerFieldUpdaterTest.class, "privateField");
39 shouldThrow();
40 } catch (RuntimeException success) {
41 assertNotNull(success.getCause());
42 }
43 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000044
Pete Gillinfbdae2c2018-03-20 14:55:37 +000045 public void checkCompareAndSetProtectedSub() {
46 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
47 AtomicIntegerFieldUpdater.newUpdater
48 (AtomicIntegerFieldUpdaterTest.class, "protectedField");
49 this.protectedField = 1;
50 assertTrue(a.compareAndSet(this, 1, 2));
51 assertTrue(a.compareAndSet(this, 2, -4));
52 assertEquals(-4, a.get(this));
53 assertFalse(a.compareAndSet(this, -5, 7));
54 assertEquals(-4, a.get(this));
55 assertTrue(a.compareAndSet(this, -4, 7));
56 assertEquals(7, a.get(this));
57 }
58 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000059
Pete Gillinfbdae2c2018-03-20 14:55:37 +000060 static class UnrelatedClass {
61 public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) {
62 obj.x = 72;
63 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
64 AtomicIntegerFieldUpdater.newUpdater
65 (AtomicIntegerFieldUpdaterTest.class, "x");
66 assertEquals(72, a.get(obj));
67 assertTrue(a.compareAndSet(obj, 72, 73));
68 assertEquals(73, a.get(obj));
69 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +000070
Pete Gillinfbdae2c2018-03-20 14:55:37 +000071 public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) {
72 try {
73 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a =
74 AtomicIntegerFieldUpdater.newUpdater
75 (AtomicIntegerFieldUpdaterTest.class, "privateField");
76 throw new AssertionError("should throw");
77 } catch (RuntimeException success) {
78 assertNotNull(success.getCause());
79 }
80 }
81 }
Calin Juravle8f0d92b2013-08-01 17:26:00 +010082
83 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) {
84 return AtomicIntegerFieldUpdater.newUpdater
85 (AtomicIntegerFieldUpdaterTest.class, fieldName);
86 }
87
88 /**
89 * Construction with non-existent field throws RuntimeException
90 */
91 public void testConstructor() {
92 try {
93 updaterFor("y");
94 shouldThrow();
95 } catch (RuntimeException success) {
96 assertNotNull(success.getCause());
97 }
98 }
99
100 /**
101 * construction with field not of given type throws IllegalArgumentException
102 */
103 public void testConstructor2() {
104 try {
105 updaterFor("z");
106 shouldThrow();
107 } catch (IllegalArgumentException success) {}
108 }
109
110 /**
111 * construction with non-volatile field throws IllegalArgumentException
112 */
113 public void testConstructor3() {
114 try {
115 updaterFor("w");
116 shouldThrow();
117 } catch (IllegalArgumentException success) {}
118 }
119
120 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000121 * construction using private field from subclass throws RuntimeException
122 */
Pete Gillinfbdae2c2018-03-20 14:55:37 +0000123 public void testPrivateFieldInSubclass() {
124 AtomicIntegerFieldUpdaterTestSubclass s =
125 new AtomicIntegerFieldUpdaterTestSubclass();
126 s.checkPrivateAccess();
127 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000128
129 /**
130 * construction from unrelated class; package access is allowed,
131 * private access is not
132 */
Pete Gillinfbdae2c2018-03-20 14:55:37 +0000133 public void testUnrelatedClassAccess() {
134 new UnrelatedClass().checkPackageAccess(this);
135 new UnrelatedClass().checkPrivateAccess(this);
136 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000137
138 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100139 * get returns the last value set or assigned
140 */
141 public void testGetSet() {
142 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
143 a = updaterFor("x");
144 x = 1;
145 assertEquals(1, a.get(this));
146 a.set(this, 2);
147 assertEquals(2, a.get(this));
148 a.set(this, -3);
149 assertEquals(-3, a.get(this));
150 }
151
152 /**
153 * get returns the last value lazySet by same thread
154 */
155 public void testGetLazySet() {
156 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
157 a = updaterFor("x");
158 x = 1;
159 assertEquals(1, a.get(this));
160 a.lazySet(this, 2);
161 assertEquals(2, a.get(this));
162 a.lazySet(this, -3);
163 assertEquals(-3, a.get(this));
164 }
165
166 /**
167 * compareAndSet succeeds in changing value if equal to expected else fails
168 */
169 public void testCompareAndSet() {
170 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
171 a = updaterFor("x");
172 x = 1;
173 assertTrue(a.compareAndSet(this, 1, 2));
174 assertTrue(a.compareAndSet(this, 2, -4));
175 assertEquals(-4, a.get(this));
176 assertFalse(a.compareAndSet(this, -5, 7));
177 assertEquals(-4, a.get(this));
178 assertTrue(a.compareAndSet(this, -4, 7));
179 assertEquals(7, a.get(this));
180 }
181
182 /**
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000183 * compareAndSet succeeds in changing protected field value if
184 * equal to expected else fails
185 */
186 public void testCompareAndSetProtected() {
187 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
188 a = updaterFor("protectedField");
189 protectedField = 1;
190 assertTrue(a.compareAndSet(this, 1, 2));
191 assertTrue(a.compareAndSet(this, 2, -4));
192 assertEquals(-4, a.get(this));
193 assertFalse(a.compareAndSet(this, -5, 7));
194 assertEquals(-4, a.get(this));
195 assertTrue(a.compareAndSet(this, -4, 7));
196 assertEquals(7, a.get(this));
197 }
198
199 /**
200 * compareAndSet succeeds in changing protected field value if
201 * equal to expected else fails
202 */
Pete Gillinfbdae2c2018-03-20 14:55:37 +0000203 public void testCompareAndSetProtectedInSubclass() {
204 AtomicIntegerFieldUpdaterTestSubclass s =
205 new AtomicIntegerFieldUpdaterTestSubclass();
206 s.checkCompareAndSetProtectedSub();
207 }
Przemyslaw Szczepaniakb8b75112016-03-11 15:59:10 +0000208
209 /**
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100210 * compareAndSet in one thread enables another waiting for value
211 * to succeed
212 */
213 public void testCompareAndSetInMultipleThreads() throws Exception {
214 x = 1;
215 final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
216 a = updaterFor("x");
217
218 Thread t = new Thread(new CheckedRunnable() {
219 public void realRun() {
220 while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3))
221 Thread.yield();
222 }});
223
224 t.start();
225 assertTrue(a.compareAndSet(this, 1, 2));
226 t.join(LONG_DELAY_MS);
227 assertFalse(t.isAlive());
228 assertEquals(3, a.get(this));
229 }
230
231 /**
232 * repeated weakCompareAndSet succeeds in changing value when equal
233 * to expected
234 */
235 public void testWeakCompareAndSet() {
236 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
237 a = updaterFor("x");
238 x = 1;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100239 do {} while (!a.weakCompareAndSet(this, 1, 2));
240 do {} while (!a.weakCompareAndSet(this, 2, -4));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100241 assertEquals(-4, a.get(this));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100242 do {} while (!a.weakCompareAndSet(this, -4, 7));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100243 assertEquals(7, a.get(this));
244 }
245
246 /**
247 * getAndSet returns previous value and sets to given value
248 */
249 public void testGetAndSet() {
250 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
251 a = updaterFor("x");
252 x = 1;
253 assertEquals(1, a.getAndSet(this, 0));
254 assertEquals(0, a.getAndSet(this, -10));
255 assertEquals(-10, a.getAndSet(this, 1));
256 }
257
258 /**
259 * getAndAdd returns previous value and adds given value
260 */
261 public void testGetAndAdd() {
262 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
263 a = updaterFor("x");
264 x = 1;
265 assertEquals(1, a.getAndAdd(this, 2));
266 assertEquals(3, a.get(this));
267 assertEquals(3, a.getAndAdd(this, -4));
268 assertEquals(-1, a.get(this));
269 }
270
271 /**
272 * getAndDecrement returns previous value and decrements
273 */
274 public void testGetAndDecrement() {
275 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
276 a = updaterFor("x");
277 x = 1;
278 assertEquals(1, a.getAndDecrement(this));
279 assertEquals(0, a.getAndDecrement(this));
280 assertEquals(-1, a.getAndDecrement(this));
281 }
282
283 /**
284 * getAndIncrement returns previous value and increments
285 */
286 public void testGetAndIncrement() {
287 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
288 a = updaterFor("x");
289 x = 1;
290 assertEquals(1, a.getAndIncrement(this));
291 assertEquals(2, a.get(this));
292 a.set(this, -2);
293 assertEquals(-2, a.getAndIncrement(this));
294 assertEquals(-1, a.getAndIncrement(this));
295 assertEquals(0, a.getAndIncrement(this));
296 assertEquals(1, a.get(this));
297 }
298
299 /**
300 * addAndGet adds given value to current, and returns current value
301 */
302 public void testAddAndGet() {
303 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
304 a = updaterFor("x");
305 x = 1;
306 assertEquals(3, a.addAndGet(this, 2));
307 assertEquals(3, a.get(this));
308 assertEquals(-1, a.addAndGet(this, -4));
309 assertEquals(-1, a.get(this));
310 }
311
312 /**
313 * decrementAndGet decrements and returns current value
314 */
315 public void testDecrementAndGet() {
316 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
317 a = updaterFor("x");
318 x = 1;
319 assertEquals(0, a.decrementAndGet(this));
320 assertEquals(-1, a.decrementAndGet(this));
321 assertEquals(-2, a.decrementAndGet(this));
322 assertEquals(-2, a.get(this));
323 }
324
325 /**
326 * incrementAndGet increments and returns current value
327 */
328 public void testIncrementAndGet() {
329 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a;
330 a = updaterFor("x");
331 x = 1;
332 assertEquals(2, a.incrementAndGet(this));
333 assertEquals(2, a.get(this));
334 a.set(this, -2);
335 assertEquals(-1, a.incrementAndGet(this));
336 assertEquals(0, a.incrementAndGet(this));
337 assertEquals(1, a.incrementAndGet(this));
338 assertEquals(1, a.get(this));
339 }
340
341}