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