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 // android-note: Removed because android doesn't restrict reflection access 34 // static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest { 35 // public void checkPrivateAccess() { 36 // try { 37 // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 38 // AtomicIntegerFieldUpdater.newUpdater 39 // (AtomicIntegerFieldUpdaterTest.class, "privateField"); 40 // shouldThrow(); 41 // } catch (RuntimeException success) { 42 // assertNotNull(success.getCause()); 43 // } 44 // } 45 46 // public void checkCompareAndSetProtectedSub() { 47 // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 48 // AtomicIntegerFieldUpdater.newUpdater 49 // (AtomicIntegerFieldUpdaterTest.class, "protectedField"); 50 // this.protectedField = 1; 51 // assertTrue(a.compareAndSet(this, 1, 2)); 52 // assertTrue(a.compareAndSet(this, 2, -4)); 53 // assertEquals(-4, a.get(this)); 54 // assertFalse(a.compareAndSet(this, -5, 7)); 55 // assertEquals(-4, a.get(this)); 56 // assertTrue(a.compareAndSet(this, -4, 7)); 57 // assertEquals(7, a.get(this)); 58 // } 59 // } 60 61 // static class UnrelatedClass { 62 // public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) { 63 // obj.x = 72; 64 // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 65 // AtomicIntegerFieldUpdater.newUpdater 66 // (AtomicIntegerFieldUpdaterTest.class, "x"); 67 // assertEquals(72, a.get(obj)); 68 // assertTrue(a.compareAndSet(obj, 72, 73)); 69 // assertEquals(73, a.get(obj)); 70 // } 71 72 // public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) { 73 // try { 74 // AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 75 // AtomicIntegerFieldUpdater.newUpdater 76 // (AtomicIntegerFieldUpdaterTest.class, "privateField"); 77 // throw new AssertionError("should throw"); 78 // } catch (RuntimeException success) { 79 // assertNotNull(success.getCause()); 80 // } 81 // } 82 // } 83 updaterFor(String fieldName)84 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) { 85 return AtomicIntegerFieldUpdater.newUpdater 86 (AtomicIntegerFieldUpdaterTest.class, fieldName); 87 } 88 89 /** 90 * Construction with non-existent field throws RuntimeException 91 */ testConstructor()92 public void testConstructor() { 93 try { 94 updaterFor("y"); 95 shouldThrow(); 96 } catch (RuntimeException success) { 97 assertNotNull(success.getCause()); 98 } 99 } 100 101 /** 102 * construction with field not of given type throws IllegalArgumentException 103 */ testConstructor2()104 public void testConstructor2() { 105 try { 106 updaterFor("z"); 107 shouldThrow(); 108 } catch (IllegalArgumentException success) {} 109 } 110 111 /** 112 * construction with non-volatile field throws IllegalArgumentException 113 */ testConstructor3()114 public void testConstructor3() { 115 try { 116 updaterFor("w"); 117 shouldThrow(); 118 } catch (IllegalArgumentException success) {} 119 } 120 121 /** 122 * construction using private field from subclass throws RuntimeException 123 */ 124 // android-note: Removed because android doesn't restrict reflection access 125 // public void testPrivateFieldInSubclass() { 126 // AtomicIntegerFieldUpdaterTestSubclass s = 127 // new AtomicIntegerFieldUpdaterTestSubclass(); 128 // s.checkPrivateAccess(); 129 // } 130 131 /** 132 * construction from unrelated class; package access is allowed, 133 * private access is not 134 */ 135 // android-note: Removed because android doesn't restrict reflection access 136 // public void testUnrelatedClassAccess() { 137 // new UnrelatedClass().checkPackageAccess(this); 138 // new UnrelatedClass().checkPrivateAccess(this); 139 // } 140 141 /** 142 * get returns the last value set or assigned 143 */ testGetSet()144 public void testGetSet() { 145 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 146 a = updaterFor("x"); 147 x = 1; 148 assertEquals(1, a.get(this)); 149 a.set(this, 2); 150 assertEquals(2, a.get(this)); 151 a.set(this, -3); 152 assertEquals(-3, a.get(this)); 153 } 154 155 /** 156 * get returns the last value lazySet by same thread 157 */ testGetLazySet()158 public void testGetLazySet() { 159 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 160 a = updaterFor("x"); 161 x = 1; 162 assertEquals(1, a.get(this)); 163 a.lazySet(this, 2); 164 assertEquals(2, a.get(this)); 165 a.lazySet(this, -3); 166 assertEquals(-3, a.get(this)); 167 } 168 169 /** 170 * compareAndSet succeeds in changing value if equal to expected else fails 171 */ testCompareAndSet()172 public void testCompareAndSet() { 173 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 174 a = updaterFor("x"); 175 x = 1; 176 assertTrue(a.compareAndSet(this, 1, 2)); 177 assertTrue(a.compareAndSet(this, 2, -4)); 178 assertEquals(-4, a.get(this)); 179 assertFalse(a.compareAndSet(this, -5, 7)); 180 assertEquals(-4, a.get(this)); 181 assertTrue(a.compareAndSet(this, -4, 7)); 182 assertEquals(7, a.get(this)); 183 } 184 185 /** 186 * compareAndSet succeeds in changing protected field value if 187 * equal to expected else fails 188 */ testCompareAndSetProtected()189 public void testCompareAndSetProtected() { 190 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 191 a = updaterFor("protectedField"); 192 protectedField = 1; 193 assertTrue(a.compareAndSet(this, 1, 2)); 194 assertTrue(a.compareAndSet(this, 2, -4)); 195 assertEquals(-4, a.get(this)); 196 assertFalse(a.compareAndSet(this, -5, 7)); 197 assertEquals(-4, a.get(this)); 198 assertTrue(a.compareAndSet(this, -4, 7)); 199 assertEquals(7, a.get(this)); 200 } 201 202 /** 203 * compareAndSet succeeds in changing protected field value if 204 * equal to expected else fails 205 */ 206 // android-note: Removed because android doesn't restrict reflection access 207 // public void testCompareAndSetProtectedInSubclass() { 208 // AtomicIntegerFieldUpdaterTestSubclass s = 209 // new AtomicIntegerFieldUpdaterTestSubclass(); 210 // s.checkCompareAndSetProtectedSub(); 211 // } 212 213 /** 214 * compareAndSet in one thread enables another waiting for value 215 * to succeed 216 */ testCompareAndSetInMultipleThreads()217 public void testCompareAndSetInMultipleThreads() throws Exception { 218 x = 1; 219 final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 220 a = updaterFor("x"); 221 222 Thread t = new Thread(new CheckedRunnable() { 223 public void realRun() { 224 while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3)) 225 Thread.yield(); 226 }}); 227 228 t.start(); 229 assertTrue(a.compareAndSet(this, 1, 2)); 230 t.join(LONG_DELAY_MS); 231 assertFalse(t.isAlive()); 232 assertEquals(3, a.get(this)); 233 } 234 235 /** 236 * repeated weakCompareAndSet succeeds in changing value when equal 237 * to expected 238 */ testWeakCompareAndSet()239 public void testWeakCompareAndSet() { 240 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 241 a = updaterFor("x"); 242 x = 1; 243 do {} while (!a.weakCompareAndSet(this, 1, 2)); 244 do {} while (!a.weakCompareAndSet(this, 2, -4)); 245 assertEquals(-4, a.get(this)); 246 do {} while (!a.weakCompareAndSet(this, -4, 7)); 247 assertEquals(7, a.get(this)); 248 } 249 250 /** 251 * getAndSet returns previous value and sets to given value 252 */ testGetAndSet()253 public void testGetAndSet() { 254 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 255 a = updaterFor("x"); 256 x = 1; 257 assertEquals(1, a.getAndSet(this, 0)); 258 assertEquals(0, a.getAndSet(this, -10)); 259 assertEquals(-10, a.getAndSet(this, 1)); 260 } 261 262 /** 263 * getAndAdd returns previous value and adds given value 264 */ testGetAndAdd()265 public void testGetAndAdd() { 266 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 267 a = updaterFor("x"); 268 x = 1; 269 assertEquals(1, a.getAndAdd(this, 2)); 270 assertEquals(3, a.get(this)); 271 assertEquals(3, a.getAndAdd(this, -4)); 272 assertEquals(-1, a.get(this)); 273 } 274 275 /** 276 * getAndDecrement returns previous value and decrements 277 */ testGetAndDecrement()278 public void testGetAndDecrement() { 279 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 280 a = updaterFor("x"); 281 x = 1; 282 assertEquals(1, a.getAndDecrement(this)); 283 assertEquals(0, a.getAndDecrement(this)); 284 assertEquals(-1, a.getAndDecrement(this)); 285 } 286 287 /** 288 * getAndIncrement returns previous value and increments 289 */ testGetAndIncrement()290 public void testGetAndIncrement() { 291 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 292 a = updaterFor("x"); 293 x = 1; 294 assertEquals(1, a.getAndIncrement(this)); 295 assertEquals(2, a.get(this)); 296 a.set(this, -2); 297 assertEquals(-2, a.getAndIncrement(this)); 298 assertEquals(-1, a.getAndIncrement(this)); 299 assertEquals(0, a.getAndIncrement(this)); 300 assertEquals(1, a.get(this)); 301 } 302 303 /** 304 * addAndGet adds given value to current, and returns current value 305 */ testAddAndGet()306 public void testAddAndGet() { 307 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 308 a = updaterFor("x"); 309 x = 1; 310 assertEquals(3, a.addAndGet(this, 2)); 311 assertEquals(3, a.get(this)); 312 assertEquals(-1, a.addAndGet(this, -4)); 313 assertEquals(-1, a.get(this)); 314 } 315 316 /** 317 * decrementAndGet decrements and returns current value 318 */ testDecrementAndGet()319 public void testDecrementAndGet() { 320 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 321 a = updaterFor("x"); 322 x = 1; 323 assertEquals(0, a.decrementAndGet(this)); 324 assertEquals(-1, a.decrementAndGet(this)); 325 assertEquals(-2, a.decrementAndGet(this)); 326 assertEquals(-2, a.get(this)); 327 } 328 329 /** 330 * incrementAndGet increments and returns current value 331 */ testIncrementAndGet()332 public void testIncrementAndGet() { 333 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 334 a = updaterFor("x"); 335 x = 1; 336 assertEquals(2, a.incrementAndGet(this)); 337 assertEquals(2, a.get(this)); 338 a.set(this, -2); 339 assertEquals(-1, a.incrementAndGet(this)); 340 assertEquals(0, a.incrementAndGet(this)); 341 assertEquals(1, a.incrementAndGet(this)); 342 assertEquals(1, a.get(this)); 343 } 344 345 } 346