blob: 204f814fab46cf1e456113bfeee4d8d67cbb3058 [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.AtomicLongFieldUpdater;
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 AtomicLongFieldUpdaterTest extends JSR166TestCase {
17 volatile long x = 0;
18 int z;
19 long w;
20
Narayan Kamath8e9a0e92015-04-28 11:40:00 +010021 // android-note: Removed because the CTS runner does a bad job of
22 // retrying tests that have suite() declarations.
23 //
24 // public static void main(String[] args) {
25 // main(suite(), args);
26 // }
27 // public static Test suite() {
28 // return new TestSuite(...);
29 // }
30
Calin Juravle8f0d92b2013-08-01 17:26:00 +010031 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) {
32 return AtomicLongFieldUpdater.newUpdater
33 (AtomicLongFieldUpdaterTest.class, fieldName);
34 }
35
36 /**
37 * Construction with non-existent field throws RuntimeException
38 */
39 public void testConstructor() {
40 try {
41 updaterFor("y");
42 shouldThrow();
43 } catch (RuntimeException success) {
44 assertNotNull(success.getCause());
45 }
46 }
47
48 /**
49 * construction with field not of given type throws IllegalArgumentException
50 */
51 public void testConstructor2() {
52 try {
53 updaterFor("z");
54 shouldThrow();
55 } catch (IllegalArgumentException success) {}
56 }
57
58 /**
59 * construction with non-volatile field throws IllegalArgumentException
60 */
61 public void testConstructor3() {
62 try {
63 updaterFor("w");
64 shouldThrow();
65 } catch (IllegalArgumentException success) {}
66 }
67
68 /**
69 * get returns the last value set or assigned
70 */
71 public void testGetSet() {
72 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
73 a = updaterFor("x");
74 x = 1;
75 assertEquals(1, a.get(this));
76 a.set(this, 2);
77 assertEquals(2, a.get(this));
78 a.set(this, -3);
79 assertEquals(-3, a.get(this));
80 }
81
82 /**
83 * get returns the last value lazySet by same thread
84 */
85 public void testGetLazySet() {
86 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
87 a = updaterFor("x");
88 x = 1;
89 assertEquals(1, a.get(this));
90 a.lazySet(this, 2);
91 assertEquals(2, a.get(this));
92 a.lazySet(this, -3);
93 assertEquals(-3, a.get(this));
94 }
95
96 /**
97 * compareAndSet succeeds in changing value if equal to expected else fails
98 */
99 public void testCompareAndSet() {
100 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
101 a = updaterFor("x");
102 x = 1;
103 assertTrue(a.compareAndSet(this, 1, 2));
104 assertTrue(a.compareAndSet(this, 2, -4));
105 assertEquals(-4, a.get(this));
106 assertFalse(a.compareAndSet(this, -5, 7));
107 assertEquals(-4, a.get(this));
108 assertTrue(a.compareAndSet(this, -4, 7));
109 assertEquals(7, a.get(this));
110 }
111
112 /**
113 * compareAndSet in one thread enables another waiting for value
114 * to succeed
115 */
116 public void testCompareAndSetInMultipleThreads() throws Exception {
117 x = 1;
118 final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
119 a = updaterFor("x");
120
121 Thread t = new Thread(new CheckedRunnable() {
122 public void realRun() {
123 while (!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3))
124 Thread.yield();
125 }});
126
127 t.start();
128 assertTrue(a.compareAndSet(this, 1, 2));
129 t.join(LONG_DELAY_MS);
130 assertFalse(t.isAlive());
131 assertEquals(3, a.get(this));
132 }
133
134 /**
135 * repeated weakCompareAndSet succeeds in changing value when equal
136 * to expected
137 */
138 public void testWeakCompareAndSet() {
139 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
140 a = updaterFor("x");
141 x = 1;
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100142 do {} while (!a.weakCompareAndSet(this, 1, 2));
143 do {} while (!a.weakCompareAndSet(this, 2, -4));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100144 assertEquals(-4, a.get(this));
Narayan Kamath8e9a0e92015-04-28 11:40:00 +0100145 do {} while (!a.weakCompareAndSet(this, -4, 7));
Calin Juravle8f0d92b2013-08-01 17:26:00 +0100146 assertEquals(7, a.get(this));
147 }
148
149 /**
150 * getAndSet returns previous value and sets to given value
151 */
152 public void testGetAndSet() {
153 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
154 a = updaterFor("x");
155 x = 1;
156 assertEquals(1, a.getAndSet(this, 0));
157 assertEquals(0, a.getAndSet(this, -10));
158 assertEquals(-10, a.getAndSet(this, 1));
159 }
160
161 /**
162 * getAndAdd returns previous value and adds given value
163 */
164 public void testGetAndAdd() {
165 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
166 a = updaterFor("x");
167 x = 1;
168 assertEquals(1, a.getAndAdd(this, 2));
169 assertEquals(3, a.get(this));
170 assertEquals(3, a.getAndAdd(this, -4));
171 assertEquals(-1, a.get(this));
172 }
173
174 /**
175 * getAndDecrement returns previous value and decrements
176 */
177 public void testGetAndDecrement() {
178 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
179 a = updaterFor("x");
180 x = 1;
181 assertEquals(1, a.getAndDecrement(this));
182 assertEquals(0, a.getAndDecrement(this));
183 assertEquals(-1, a.getAndDecrement(this));
184 }
185
186 /**
187 * getAndIncrement returns previous value and increments
188 */
189 public void testGetAndIncrement() {
190 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
191 a = updaterFor("x");
192 x = 1;
193 assertEquals(1, a.getAndIncrement(this));
194 assertEquals(2, a.get(this));
195 a.set(this, -2);
196 assertEquals(-2, a.getAndIncrement(this));
197 assertEquals(-1, a.getAndIncrement(this));
198 assertEquals(0, a.getAndIncrement(this));
199 assertEquals(1, a.get(this));
200 }
201
202 /**
203 * addAndGet adds given value to current, and returns current value
204 */
205 public void testAddAndGet() {
206 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
207 a = updaterFor("x");
208 x = 1;
209 assertEquals(3, a.addAndGet(this, 2));
210 assertEquals(3, a.get(this));
211 assertEquals(-1, a.addAndGet(this, -4));
212 assertEquals(-1, a.get(this));
213 }
214
215 /**
216 * decrementAndGet decrements and returns current value
217 */
218 public void testDecrementAndGet() {
219 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
220 a = updaterFor("x");
221 x = 1;
222 assertEquals(0, a.decrementAndGet(this));
223 assertEquals(-1, a.decrementAndGet(this));
224 assertEquals(-2, a.decrementAndGet(this));
225 assertEquals(-2, a.get(this));
226 }
227
228 /**
229 * incrementAndGet increments and returns current value
230 */
231 public void testIncrementAndGet() {
232 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
233 a = updaterFor("x");
234 x = 1;
235 assertEquals(2, a.incrementAndGet(this));
236 assertEquals(2, a.get(this));
237 a.set(this, -2);
238 assertEquals(-1, a.incrementAndGet(this));
239 assertEquals(0, a.incrementAndGet(this));
240 assertEquals(1, a.incrementAndGet(this));
241 assertEquals(1, a.get(this));
242 }
243
244}