1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 */ 22 23 /* 24 * This file is available under and governed by the GNU General Public 25 * License version 2 only, as published by the Free Software Foundation. 26 * However, the following notice accompanied the original version of this 27 * file: 28 * 29 * Written by Doug Lea with assistance from members of JCP JSR-166 30 * Expert Group and released to the public domain, as explained at 31 * http://creativecommons.org/publicdomain/zero/1.0/ 32 * Other contributors include Andrew Wright, Jeffrey Hayes, 33 * Pat Fisher, Mike Judd. 34 */ 35 36 import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; 37 38 import junit.framework.Test; 39 import junit.framework.TestSuite; 40 41 public class AtomicIntegerFieldUpdaterTest extends JSR166TestCase { 42 volatile int x = 0; 43 protected volatile int protectedField; 44 private volatile int privateField; 45 int w; 46 float z; 47 public static void main(String[] args) { 48 main(suite(), args); 49 } 50 public static Test suite() { 51 return new TestSuite(AtomicIntegerFieldUpdaterTest.class); 52 } 53 54 // for testing subclass access 55 static class AtomicIntegerFieldUpdaterTestSubclass extends AtomicIntegerFieldUpdaterTest { 56 public void checkPrivateAccess() { 57 try { 58 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 59 AtomicIntegerFieldUpdater.newUpdater 60 (AtomicIntegerFieldUpdaterTest.class, "privateField"); 61 shouldThrow(); 62 } catch (RuntimeException success) { 63 assertNotNull(success.getCause()); 64 } 65 } 66 67 public void checkCompareAndSetProtectedSub() { 68 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 69 AtomicIntegerFieldUpdater.newUpdater 70 (AtomicIntegerFieldUpdaterTest.class, "protectedField"); 71 this.protectedField = 1; 72 assertTrue(a.compareAndSet(this, 1, 2)); 73 assertTrue(a.compareAndSet(this, 2, -4)); 74 assertEquals(-4, a.get(this)); 75 assertFalse(a.compareAndSet(this, -5, 7)); 76 assertEquals(-4, a.get(this)); 77 assertTrue(a.compareAndSet(this, -4, 7)); 78 assertEquals(7, a.get(this)); 79 } 80 } 81 82 static class UnrelatedClass { 83 public void checkPackageAccess(AtomicIntegerFieldUpdaterTest obj) { 84 obj.x = 72; 85 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 86 AtomicIntegerFieldUpdater.newUpdater 87 (AtomicIntegerFieldUpdaterTest.class, "x"); 88 assertEquals(72, a.get(obj)); 89 assertTrue(a.compareAndSet(obj, 72, 73)); 90 assertEquals(73, a.get(obj)); 91 } 92 93 public void checkPrivateAccess(AtomicIntegerFieldUpdaterTest obj) { 94 try { 95 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a = 96 AtomicIntegerFieldUpdater.newUpdater 97 (AtomicIntegerFieldUpdaterTest.class, "privateField"); 98 throw new AssertionError("should throw"); 99 } catch (RuntimeException success) { 100 assertNotNull(success.getCause()); 101 } 102 } 103 } 104 105 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> updaterFor(String fieldName) { 106 return AtomicIntegerFieldUpdater.newUpdater 107 (AtomicIntegerFieldUpdaterTest.class, fieldName); 108 } 109 110 /** 111 * Construction with non-existent field throws RuntimeException 112 */ 113 public void testConstructor() { 114 try { 115 updaterFor("y"); 116 shouldThrow(); 117 } catch (RuntimeException success) { 118 assertNotNull(success.getCause()); 119 } 120 } 121 122 /** 123 * construction with field not of given type throws IllegalArgumentException 124 */ 125 public void testConstructor2() { 126 try { 127 updaterFor("z"); 128 shouldThrow(); 129 } catch (IllegalArgumentException success) {} 130 } 131 132 /** 133 * construction with non-volatile field throws IllegalArgumentException 134 */ 135 public void testConstructor3() { 136 try { 137 updaterFor("w"); 138 shouldThrow(); 139 } catch (IllegalArgumentException success) {} 140 } 141 142 /** 143 * construction using private field from subclass throws RuntimeException 144 */ 145 public void exclude_8187607_testPrivateFieldInSubclass() { 146 AtomicIntegerFieldUpdaterTestSubclass s = 147 new AtomicIntegerFieldUpdaterTestSubclass(); 148 s.checkPrivateAccess(); 149 } 150 151 /** 152 * construction from unrelated class; package access is allowed, 153 * private access is not 154 */ 155 public void exclude_8187607_testUnrelatedClassAccess() { 156 new UnrelatedClass().checkPackageAccess(this); 157 new UnrelatedClass().checkPrivateAccess(this); 158 } 159 160 /** 161 * get returns the last value set or assigned 162 */ 163 public void testGetSet() { 164 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 165 a = updaterFor("x"); 166 x = 1; 167 assertEquals(1, a.get(this)); 168 a.set(this, 2); 169 assertEquals(2, a.get(this)); 170 a.set(this, -3); 171 assertEquals(-3, a.get(this)); 172 } 173 174 /** 175 * get returns the last value lazySet by same thread 176 */ 177 public void testGetLazySet() { 178 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 179 a = updaterFor("x"); 180 x = 1; 181 assertEquals(1, a.get(this)); 182 a.lazySet(this, 2); 183 assertEquals(2, a.get(this)); 184 a.lazySet(this, -3); 185 assertEquals(-3, a.get(this)); 186 } 187 188 /** 189 * compareAndSet succeeds in changing value if equal to expected else fails 190 */ 191 public void testCompareAndSet() { 192 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 193 a = updaterFor("x"); 194 x = 1; 195 assertTrue(a.compareAndSet(this, 1, 2)); 196 assertTrue(a.compareAndSet(this, 2, -4)); 197 assertEquals(-4, a.get(this)); 198 assertFalse(a.compareAndSet(this, -5, 7)); 199 assertEquals(-4, a.get(this)); 200 assertTrue(a.compareAndSet(this, -4, 7)); 201 assertEquals(7, a.get(this)); 202 } 203 204 /** 205 * compareAndSet succeeds in changing protected field value if 206 * equal to expected else fails 207 */ 208 public void testCompareAndSetProtected() { 209 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 210 a = updaterFor("protectedField"); 211 protectedField = 1; 212 assertTrue(a.compareAndSet(this, 1, 2)); 213 assertTrue(a.compareAndSet(this, 2, -4)); 214 assertEquals(-4, a.get(this)); 215 assertFalse(a.compareAndSet(this, -5, 7)); 216 assertEquals(-4, a.get(this)); 217 assertTrue(a.compareAndSet(this, -4, 7)); 218 assertEquals(7, a.get(this)); 219 } 220 221 /** 222 * compareAndSet succeeds in changing protected field value if 223 * equal to expected else fails 224 */ 225 public void testCompareAndSetProtectedInSubclass() { 226 AtomicIntegerFieldUpdaterTestSubclass s = 227 new AtomicIntegerFieldUpdaterTestSubclass(); 228 s.checkCompareAndSetProtectedSub(); 229 } 230 231 /** 232 * compareAndSet in one thread enables another waiting for value 233 * to succeed 234 */ 235 public void testCompareAndSetInMultipleThreads() throws Exception { 236 x = 1; 237 final AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 238 a = updaterFor("x"); 239 240 Thread t = new Thread(new CheckedRunnable() { 241 public void realRun() { 242 while (!a.compareAndSet(AtomicIntegerFieldUpdaterTest.this, 2, 3)) 243 Thread.yield(); 244 }}); 245 246 t.start(); 247 assertTrue(a.compareAndSet(this, 1, 2)); 248 t.join(LONG_DELAY_MS); 249 assertFalse(t.isAlive()); 250 assertEquals(3, a.get(this)); 251 } 252 253 /** 254 * repeated weakCompareAndSet succeeds in changing value when equal 255 * to expected 256 */ 257 public void testWeakCompareAndSet() { 258 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 259 a = updaterFor("x"); 260 x = 1; 261 do {} while (!a.weakCompareAndSet(this, 1, 2)); 262 do {} while (!a.weakCompareAndSet(this, 2, -4)); 263 assertEquals(-4, a.get(this)); 264 do {} while (!a.weakCompareAndSet(this, -4, 7)); 265 assertEquals(7, a.get(this)); 266 } 267 268 /** 269 * getAndSet returns previous value and sets to given value 270 */ 271 public void testGetAndSet() { 272 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 273 a = updaterFor("x"); 274 x = 1; 275 assertEquals(1, a.getAndSet(this, 0)); 276 assertEquals(0, a.getAndSet(this, -10)); 277 assertEquals(-10, a.getAndSet(this, 1)); 278 } 279 280 /** 281 * getAndAdd returns previous value and adds given value 282 */ 283 public void testGetAndAdd() { 284 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 285 a = updaterFor("x"); 286 x = 1; 287 assertEquals(1, a.getAndAdd(this, 2)); 288 assertEquals(3, a.get(this)); 289 assertEquals(3, a.getAndAdd(this, -4)); 290 assertEquals(-1, a.get(this)); 291 } 292 293 /** 294 * getAndDecrement returns previous value and decrements 295 */ 296 public void testGetAndDecrement() { 297 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 298 a = updaterFor("x"); 299 x = 1; 300 assertEquals(1, a.getAndDecrement(this)); 301 assertEquals(0, a.getAndDecrement(this)); 302 assertEquals(-1, a.getAndDecrement(this)); 303 } 304 305 /** 306 * getAndIncrement returns previous value and increments 307 */ 308 public void testGetAndIncrement() { 309 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 310 a = updaterFor("x"); 311 x = 1; 312 assertEquals(1, a.getAndIncrement(this)); 313 assertEquals(2, a.get(this)); 314 a.set(this, -2); 315 assertEquals(-2, a.getAndIncrement(this)); 316 assertEquals(-1, a.getAndIncrement(this)); 317 assertEquals(0, a.getAndIncrement(this)); 318 assertEquals(1, a.get(this)); 319 } 320 321 /** 322 * addAndGet adds given value to current, and returns current value 323 */ 324 public void testAddAndGet() { 325 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 326 a = updaterFor("x"); 327 x = 1; 328 assertEquals(3, a.addAndGet(this, 2)); 329 assertEquals(3, a.get(this)); 330 assertEquals(-1, a.addAndGet(this, -4)); 331 assertEquals(-1, a.get(this)); 332 } 333 334 /** 335 * decrementAndGet decrements and returns current value 336 */ 337 public void testDecrementAndGet() { 338 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 339 a = updaterFor("x"); 340 x = 1; 341 assertEquals(0, a.decrementAndGet(this)); 342 assertEquals(-1, a.decrementAndGet(this)); 343 assertEquals(-2, a.decrementAndGet(this)); 344 assertEquals(-2, a.get(this)); 345 } 346 347 /** 348 * incrementAndGet increments and returns current value 349 */ 350 public void testIncrementAndGet() { 351 AtomicIntegerFieldUpdater<AtomicIntegerFieldUpdaterTest> a; 352 a = updaterFor("x"); 353 x = 1; 354 assertEquals(2, a.incrementAndGet(this)); 355 assertEquals(2, a.get(this)); 356 a.set(this, -2); 357 assertEquals(-1, a.incrementAndGet(this)); 358 assertEquals(0, a.incrementAndGet(this)); 359 assertEquals(1, a.incrementAndGet(this)); 360 assertEquals(1, a.get(this)); 361 } 362 363 }