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 int z; 19 long w; 20 21 // android-note: Removed because the CTS runner does a bad job of 22 // retrying tests that have suite() declarations. 23 // 24 // public static void main(String[] args) { 25 // main(suite(), args); 26 // } 27 // public static Test suite() { 28 // return new TestSuite(...); 29 // } 30 updaterFor(String fieldName)31 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> updaterFor(String fieldName) { 32 return AtomicLongFieldUpdater.newUpdater 33 (AtomicLongFieldUpdaterTest.class, fieldName); 34 } 35 36 /** 37 * Construction with non-existent field throws RuntimeException 38 */ testConstructor()39 public void testConstructor() { 40 try { 41 updaterFor("y"); 42 shouldThrow(); 43 } catch (RuntimeException success) { 44 assertNotNull(success.getCause()); 45 } 46 } 47 48 /** 49 * construction with field not of given type throws IllegalArgumentException 50 */ testConstructor2()51 public void testConstructor2() { 52 try { 53 updaterFor("z"); 54 shouldThrow(); 55 } catch (IllegalArgumentException success) {} 56 } 57 58 /** 59 * construction with non-volatile field throws IllegalArgumentException 60 */ testConstructor3()61 public void testConstructor3() { 62 try { 63 updaterFor("w"); 64 shouldThrow(); 65 } catch (IllegalArgumentException success) {} 66 } 67 68 /** 69 * get returns the last value set or assigned 70 */ testGetSet()71 public void testGetSet() { 72 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 73 a = updaterFor("x"); 74 x = 1; 75 assertEquals(1, a.get(this)); 76 a.set(this, 2); 77 assertEquals(2, a.get(this)); 78 a.set(this, -3); 79 assertEquals(-3, a.get(this)); 80 } 81 82 /** 83 * get returns the last value lazySet by same thread 84 */ testGetLazySet()85 public void testGetLazySet() { 86 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 87 a = updaterFor("x"); 88 x = 1; 89 assertEquals(1, a.get(this)); 90 a.lazySet(this, 2); 91 assertEquals(2, a.get(this)); 92 a.lazySet(this, -3); 93 assertEquals(-3, a.get(this)); 94 } 95 96 /** 97 * compareAndSet succeeds in changing value if equal to expected else fails 98 */ testCompareAndSet()99 public void testCompareAndSet() { 100 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 101 a = updaterFor("x"); 102 x = 1; 103 assertTrue(a.compareAndSet(this, 1, 2)); 104 assertTrue(a.compareAndSet(this, 2, -4)); 105 assertEquals(-4, a.get(this)); 106 assertFalse(a.compareAndSet(this, -5, 7)); 107 assertEquals(-4, a.get(this)); 108 assertTrue(a.compareAndSet(this, -4, 7)); 109 assertEquals(7, a.get(this)); 110 } 111 112 /** 113 * compareAndSet in one thread enables another waiting for value 114 * to succeed 115 */ testCompareAndSetInMultipleThreads()116 public void testCompareAndSetInMultipleThreads() throws Exception { 117 x = 1; 118 final AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 119 a = updaterFor("x"); 120 121 Thread t = new Thread(new CheckedRunnable() { 122 public void realRun() { 123 while (!a.compareAndSet(AtomicLongFieldUpdaterTest.this, 2, 3)) 124 Thread.yield(); 125 }}); 126 127 t.start(); 128 assertTrue(a.compareAndSet(this, 1, 2)); 129 t.join(LONG_DELAY_MS); 130 assertFalse(t.isAlive()); 131 assertEquals(3, a.get(this)); 132 } 133 134 /** 135 * repeated weakCompareAndSet succeeds in changing value when equal 136 * to expected 137 */ testWeakCompareAndSet()138 public void testWeakCompareAndSet() { 139 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 140 a = updaterFor("x"); 141 x = 1; 142 do {} while (!a.weakCompareAndSet(this, 1, 2)); 143 do {} while (!a.weakCompareAndSet(this, 2, -4)); 144 assertEquals(-4, a.get(this)); 145 do {} while (!a.weakCompareAndSet(this, -4, 7)); 146 assertEquals(7, a.get(this)); 147 } 148 149 /** 150 * getAndSet returns previous value and sets to given value 151 */ testGetAndSet()152 public void testGetAndSet() { 153 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 154 a = updaterFor("x"); 155 x = 1; 156 assertEquals(1, a.getAndSet(this, 0)); 157 assertEquals(0, a.getAndSet(this, -10)); 158 assertEquals(-10, a.getAndSet(this, 1)); 159 } 160 161 /** 162 * getAndAdd returns previous value and adds given value 163 */ testGetAndAdd()164 public void testGetAndAdd() { 165 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 166 a = updaterFor("x"); 167 x = 1; 168 assertEquals(1, a.getAndAdd(this, 2)); 169 assertEquals(3, a.get(this)); 170 assertEquals(3, a.getAndAdd(this, -4)); 171 assertEquals(-1, a.get(this)); 172 } 173 174 /** 175 * getAndDecrement returns previous value and decrements 176 */ testGetAndDecrement()177 public void testGetAndDecrement() { 178 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 179 a = updaterFor("x"); 180 x = 1; 181 assertEquals(1, a.getAndDecrement(this)); 182 assertEquals(0, a.getAndDecrement(this)); 183 assertEquals(-1, a.getAndDecrement(this)); 184 } 185 186 /** 187 * getAndIncrement returns previous value and increments 188 */ testGetAndIncrement()189 public void testGetAndIncrement() { 190 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 191 a = updaterFor("x"); 192 x = 1; 193 assertEquals(1, a.getAndIncrement(this)); 194 assertEquals(2, a.get(this)); 195 a.set(this, -2); 196 assertEquals(-2, a.getAndIncrement(this)); 197 assertEquals(-1, a.getAndIncrement(this)); 198 assertEquals(0, a.getAndIncrement(this)); 199 assertEquals(1, a.get(this)); 200 } 201 202 /** 203 * addAndGet adds given value to current, and returns current value 204 */ testAddAndGet()205 public void testAddAndGet() { 206 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 207 a = updaterFor("x"); 208 x = 1; 209 assertEquals(3, a.addAndGet(this, 2)); 210 assertEquals(3, a.get(this)); 211 assertEquals(-1, a.addAndGet(this, -4)); 212 assertEquals(-1, a.get(this)); 213 } 214 215 /** 216 * decrementAndGet decrements and returns current value 217 */ testDecrementAndGet()218 public void testDecrementAndGet() { 219 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 220 a = updaterFor("x"); 221 x = 1; 222 assertEquals(0, a.decrementAndGet(this)); 223 assertEquals(-1, a.decrementAndGet(this)); 224 assertEquals(-2, a.decrementAndGet(this)); 225 assertEquals(-2, a.get(this)); 226 } 227 228 /** 229 * incrementAndGet increments and returns current value 230 */ testIncrementAndGet()231 public void testIncrementAndGet() { 232 AtomicLongFieldUpdater<AtomicLongFieldUpdaterTest> a; 233 a = updaterFor("x"); 234 x = 1; 235 assertEquals(2, a.incrementAndGet(this)); 236 assertEquals(2, a.get(this)); 237 a.set(this, -2); 238 assertEquals(-1, a.incrementAndGet(this)); 239 assertEquals(0, a.incrementAndGet(this)); 240 assertEquals(1, a.incrementAndGet(this)); 241 assertEquals(1, a.get(this)); 242 } 243 244 } 245