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 protected volatile int protectedField; 19 private volatile int privateField; 20 int w; 21 float z; 22 // 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() { 29 // return new TestSuite(AtomicIntegerFieldUpdaterTest.class); 30 // } 31 32 // for testing subclass access 33 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 } 44 45 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 } 59 60 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 } 70 71 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 } 82 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 /** 121 * construction using private field from subclass throws RuntimeException 122 */ 123 public void testPrivateFieldInSubclass() { 124 AtomicIntegerFieldUpdaterTestSubclass s = 125 new AtomicIntegerFieldUpdaterTestSubclass(); 126 s.checkPrivateAccess(); 127 } 128 129 /** 130 * construction from unrelated class; package access is allowed, 131 * private access is not 132 */ 133 public void testUnrelatedClassAccess() { 134 new UnrelatedClass().checkPackageAccess(this); 135 new UnrelatedClass().checkPrivateAccess(this); 136 } 137 138 /** 139 * 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 /** 183 * 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 */ 203 public void testCompareAndSetProtectedInSubclass() { 204 AtomicIntegerFieldUpdaterTestSubclass s = 205 new AtomicIntegerFieldUpdaterTestSubclass(); 206 s.checkCompareAndSetProtectedSub(); 207 } 208 209 /** 210 * 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; 239 do {} while (!a.weakCompareAndSet(this, 1, 2)); 240 do {} while (!a.weakCompareAndSet(this, 2, -4)); 241 assertEquals(-4, a.get(this)); 242 do {} while (!a.weakCompareAndSet(this, -4, 7)); 243 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 } 342