1 /* 2 * Written by Doug Lea and Martin Buchholz with assistance from 3 * members of JCP JSR-166 Expert Group and released to the public 4 * domain, as explained at 5 * http://creativecommons.org/publicdomain/zero/1.0/ 6 */ 7 8 /* 9 * Source: 10 * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck-jsr166e/AtomicDoubleTest.java?revision=1.8 11 * (Modified to adapt to guava coding conventions) 12 */ 13 14 package com.google.common.util.concurrent; 15 16 import junit.framework.*; 17 18 /** 19 * Unit test for {@link AtomicDouble}. 20 */ 21 public class AtomicDoubleTest extends JSR166TestCase { 22 23 private static final double[] VALUES = { 24 Double.NEGATIVE_INFINITY, 25 -Double.MAX_VALUE, 26 (double) Long.MIN_VALUE, 27 (double) Integer.MIN_VALUE, 28 -Math.PI, 29 -1.0, 30 -Double.MIN_VALUE, 31 -0.0, 32 +0.0, 33 Double.MIN_VALUE, 34 1.0, 35 Math.PI, 36 (double) Integer.MAX_VALUE, 37 (double) Long.MAX_VALUE, 38 Double.MAX_VALUE, 39 Double.POSITIVE_INFINITY, 40 Double.NaN, 41 Float.MAX_VALUE, 42 }; 43 44 /** The notion of equality used by AtomicDouble */ bitEquals(double x, double y)45 static boolean bitEquals(double x, double y) { 46 return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); 47 } 48 assertBitEquals(double x, double y)49 static void assertBitEquals(double x, double y) { 50 assertEquals(Double.doubleToRawLongBits(x), 51 Double.doubleToRawLongBits(y)); 52 } 53 54 /** 55 * constructor initializes to given value 56 */ testConstructor()57 public void testConstructor() { 58 for (double x : VALUES) { 59 AtomicDouble a = new AtomicDouble(x); 60 assertBitEquals(x, a.get()); 61 } 62 } 63 64 /** 65 * default constructed initializes to zero 66 */ testConstructor2()67 public void testConstructor2() { 68 AtomicDouble a = new AtomicDouble(); 69 assertBitEquals(0.0, a.get()); 70 } 71 72 /** 73 * get returns the last value set 74 */ testGetSet()75 public void testGetSet() { 76 AtomicDouble at = new AtomicDouble(1.0); 77 assertBitEquals(1.0, at.get()); 78 for (double x : VALUES) { 79 at.set(x); 80 assertBitEquals(x, at.get()); 81 } 82 } 83 84 /** 85 * get returns the last value lazySet in same thread 86 */ testGetLazySet()87 public void testGetLazySet() { 88 AtomicDouble at = new AtomicDouble(1.0); 89 assertBitEquals(1.0, at.get()); 90 for (double x : VALUES) { 91 at.lazySet(x); 92 assertBitEquals(x, at.get()); 93 } 94 } 95 96 /** 97 * compareAndSet succeeds in changing value if equal to expected else fails 98 */ testCompareAndSet()99 public void testCompareAndSet() { 100 double prev = Math.E; 101 double unused = Math.E + Math.PI; 102 AtomicDouble at = new AtomicDouble(prev); 103 for (double x : VALUES) { 104 assertBitEquals(prev, at.get()); 105 assertFalse(at.compareAndSet(unused, x)); 106 assertBitEquals(prev, at.get()); 107 assertTrue(at.compareAndSet(prev, x)); 108 assertBitEquals(x, at.get()); 109 prev = x; 110 } 111 } 112 113 /** 114 * compareAndSet in one thread enables another waiting for value 115 * to succeed 116 */ 117 testCompareAndSetInMultipleThreads()118 public void testCompareAndSetInMultipleThreads() throws Exception { 119 final AtomicDouble at = new AtomicDouble(1.0); 120 Thread t = newStartedThread(new CheckedRunnable() { 121 public void realRun() { 122 while (!at.compareAndSet(2.0, 3.0)) { 123 Thread.yield(); 124 } 125 }}); 126 127 assertTrue(at.compareAndSet(1.0, 2.0)); 128 awaitTermination(t); 129 assertBitEquals(3.0, at.get()); 130 } 131 132 /** 133 * repeated weakCompareAndSet succeeds in changing value when equal 134 * to expected 135 */ testWeakCompareAndSet()136 public void testWeakCompareAndSet() { 137 double prev = Math.E; 138 double unused = Math.E + Math.PI; 139 AtomicDouble at = new AtomicDouble(prev); 140 for (double x : VALUES) { 141 assertBitEquals(prev, at.get()); 142 assertFalse(at.weakCompareAndSet(unused, x)); 143 assertBitEquals(prev, at.get()); 144 while (!at.weakCompareAndSet(prev, x)) { 145 ; 146 } 147 assertBitEquals(x, at.get()); 148 prev = x; 149 } 150 } 151 152 /** 153 * getAndSet returns previous value and sets to given value 154 */ testGetAndSet()155 public void testGetAndSet() { 156 double prev = Math.E; 157 AtomicDouble at = new AtomicDouble(prev); 158 for (double x : VALUES) { 159 assertBitEquals(prev, at.getAndSet(x)); 160 prev = x; 161 } 162 } 163 164 /** 165 * getAndAdd returns previous value and adds given value 166 */ testGetAndAdd()167 public void testGetAndAdd() { 168 for (double x : VALUES) { 169 for (double y : VALUES) { 170 AtomicDouble a = new AtomicDouble(x); 171 double z = a.getAndAdd(y); 172 assertBitEquals(x, z); 173 assertBitEquals(x + y, a.get()); 174 } 175 } 176 } 177 178 /** 179 * addAndGet adds given value to current, and returns current value 180 */ testAddAndGet()181 public void testAddAndGet() { 182 for (double x : VALUES) { 183 for (double y : VALUES) { 184 AtomicDouble a = new AtomicDouble(x); 185 double z = a.addAndGet(y); 186 assertBitEquals(x + y, z); 187 assertBitEquals(x + y, a.get()); 188 } 189 } 190 } 191 192 /** 193 * a deserialized serialized atomic holds same value 194 */ testSerialization()195 public void testSerialization() throws Exception { 196 AtomicDouble a = new AtomicDouble(); 197 AtomicDouble b = serialClone(a); 198 assertNotSame(a, b); 199 a.set(-22.0); 200 AtomicDouble c = serialClone(a); 201 assertNotSame(b, c); 202 assertBitEquals(-22.0, a.get()); 203 assertBitEquals(0.0, b.get()); 204 assertBitEquals(-22.0, c.get()); 205 for (double x : VALUES) { 206 AtomicDouble d = new AtomicDouble(x); 207 assertBitEquals(serialClone(d).get(), d.get()); 208 } 209 } 210 211 /** 212 * toString returns current value 213 */ testToString()214 public void testToString() { 215 AtomicDouble at = new AtomicDouble(); 216 assertEquals("0.0", at.toString()); 217 for (double x : VALUES) { 218 at.set(x); 219 assertEquals(Double.toString(x), at.toString()); 220 } 221 } 222 223 /** 224 * intValue returns current value. 225 */ testIntValue()226 public void testIntValue() { 227 AtomicDouble at = new AtomicDouble(); 228 assertEquals(0, at.intValue()); 229 for (double x : VALUES) { 230 at.set(x); 231 assertEquals((int) x, at.intValue()); 232 } 233 } 234 235 /** 236 * longValue returns current value. 237 */ testLongValue()238 public void testLongValue() { 239 AtomicDouble at = new AtomicDouble(); 240 assertEquals(0L, at.longValue()); 241 for (double x : VALUES) { 242 at.set(x); 243 assertEquals((long) x, at.longValue()); 244 } 245 } 246 247 /** 248 * floatValue returns current value. 249 */ testFloatValue()250 public void testFloatValue() { 251 AtomicDouble at = new AtomicDouble(); 252 assertEquals(0.0f, at.floatValue()); 253 for (double x : VALUES) { 254 at.set(x); 255 assertEquals((float) x, at.floatValue()); 256 } 257 } 258 259 /** 260 * doubleValue returns current value. 261 */ testDoubleValue()262 public void testDoubleValue() { 263 AtomicDouble at = new AtomicDouble(); 264 assertEquals(0.0d, at.doubleValue()); 265 for (double x : VALUES) { 266 at.set(x); 267 assertBitEquals(x, at.doubleValue()); 268 } 269 } 270 271 /** 272 * compareAndSet treats +0.0 and -0.0 as distinct values 273 */ testDistinctZeros()274 public void testDistinctZeros() { 275 AtomicDouble at = new AtomicDouble(+0.0); 276 assertFalse(at.compareAndSet(-0.0, 7.0)); 277 assertFalse(at.weakCompareAndSet(-0.0, 7.0)); 278 assertBitEquals(+0.0, at.get()); 279 assertTrue(at.compareAndSet(+0.0, -0.0)); 280 assertBitEquals(-0.0, at.get()); 281 assertFalse(at.compareAndSet(+0.0, 7.0)); 282 assertFalse(at.weakCompareAndSet(+0.0, 7.0)); 283 assertBitEquals(-0.0, at.get()); 284 } 285 } 286