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 protected volatile long protectedField; 19 private volatile long privateField; 20 long 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(AtomicLongFieldUpdaterTest.class); 30 // } 31 32 // for testing subclass access 33 static class AtomicLongFieldUpdaterTestSubclass extends AtomicLongFieldUpdaterTest { checkPrivateAccess()34 public void checkPrivateAccess() { 35 try { 36 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a = 37 AtomicLongFieldUpdater.newUpdater 38 (AtomicLongFieldUpdaterTest.class, "privateField"); 39 shouldThrow(); 40 } catch (RuntimeException success) { 41 assertNotNull(success.getCause()); 42 } 43 } 44 checkCompareAndSetProtectedSub()45 public void checkCompareAndSetProtectedSub() { 46 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a = 47 AtomicLongFieldUpdater.newUpdater 48 (AtomicLongFieldUpdaterTest.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 { checkPackageAccess(AtomicLongFieldUpdaterTest obj)61 public void checkPackageAccess(AtomicLongFieldUpdaterTest obj) { 62 obj.x = 72L; 63 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a = 64 AtomicLongFieldUpdater.newUpdater 65 (AtomicLongFieldUpdaterTest.class, "x"); 66 assertEquals(72L, a.get(obj)); 67 assertTrue(a.compareAndSet(obj, 72L, 73L)); 68 assertEquals(73L, a.get(obj)); 69 } 70 checkPrivateAccess(AtomicLongFieldUpdaterTest obj)71 public void checkPrivateAccess(AtomicLongFieldUpdaterTest obj) { 72 try { 73 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a = 74 AtomicLongFieldUpdater.newUpdater 75 (AtomicLongFieldUpdaterTest.class, "privateField"); 76 throw new AssertionError("should throw"); 77 } catch (RuntimeException success) { 78 assertNotNull(success.getCause()); 79 } 80 } 81 } 82 updaterFor(String fieldName)83 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) { 84 return AtomicLongFieldUpdater.newUpdater 85 (AtomicLongFieldUpdaterTest.class, fieldName); 86 } 87 88 /** 89 * Construction with non-existent field throws RuntimeException 90 */ testConstructor()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 */ testConstructor2()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 */ testConstructor3()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 */ testPrivateFieldInSubclass()123 public void testPrivateFieldInSubclass() { 124 AtomicLongFieldUpdaterTestSubclass s = 125 new AtomicLongFieldUpdaterTestSubclass(); 126 s.checkPrivateAccess(); 127 } 128 129 /** 130 * construction from unrelated class; package access is allowed, 131 * private access is not 132 */ testUnrelatedClassAccess()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 */ testGetSet()141 public void testGetSet() { 142 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testGetLazySet()155 public void testGetLazySet() { 156 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testCompareAndSet()169 public void testCompareAndSet() { 170 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testCompareAndSetProtected()186 public void testCompareAndSetProtected() { 187 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testCompareAndSetProtectedInSubclass()203 public void testCompareAndSetProtectedInSubclass() { 204 AtomicLongFieldUpdaterTestSubclass s = 205 new AtomicLongFieldUpdaterTestSubclass(); 206 s.checkCompareAndSetProtectedSub(); 207 } 208 209 /** 210 * compareAndSet in one thread enables another waiting for value 211 * to succeed 212 */ testCompareAndSetInMultipleThreads()213 public void testCompareAndSetInMultipleThreads() throws Exception { 214 x = 1; 215 final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 216 a = updaterFor("x"); 217 218 Thread t = new Thread(new CheckedRunnable() { 219 public void realRun() { 220 while (!a.compareAndSet(AtomicLongFieldUpdaterTest.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 */ testWeakCompareAndSet()235 public void testWeakCompareAndSet() { 236 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testGetAndSet()249 public void testGetAndSet() { 250 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testGetAndAdd()261 public void testGetAndAdd() { 262 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testGetAndDecrement()274 public void testGetAndDecrement() { 275 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testGetAndIncrement()286 public void testGetAndIncrement() { 287 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testAddAndGet()302 public void testAddAndGet() { 303 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testDecrementAndGet()315 public void testDecrementAndGet() { 316 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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 */ testIncrementAndGet()328 public void testIncrementAndGet() { 329 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> 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