• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 java.util.concurrent.atomic.AtomicLongFieldUpdater;
12 
13 import junit.framework.Test;
14 import junit.framework.TestSuite;
15 
16 public class AtomicLongFieldUpdaterTest extends JSR166TestCase {
17     volatile long x = 0;
18     int z;
19     long w;
20 
21     // 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 
updaterFor(String fieldName)31     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      */
testConstructor()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      */
testConstructor2()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      */
testConstructor3()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      */
testGetSet()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      */
testGetLazySet()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      */
testCompareAndSet()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      */
testCompareAndSetInMultipleThreads()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      */
testWeakCompareAndSet()138     public void testWeakCompareAndSet() {
139         AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a;
140         a = updaterFor("x");
141         x = 1;
142         do {} while (!a.weakCompareAndSet(this, 1, 2));
143         do {} while (!a.weakCompareAndSet(this, 2, -4));
144         assertEquals(-4, a.get(this));
145         do {} while (!a.weakCompareAndSet(this, -4, 7));
146         assertEquals(7, a.get(this));
147     }
148 
149     /**
150      * getAndSet returns previous value and sets to given value
151      */
testGetAndSet()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      */
testGetAndAdd()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      */
testGetAndDecrement()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      */
testGetAndIncrement()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      */
testAddAndGet()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      */
testDecrementAndGet()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      */
testIncrementAndGet()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 }
245