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