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