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 14package com.google.common.util.concurrent; 15 16import junit.framework.*; 17 18/** 19 * Unit test for {@link AtomicDouble}. 20 */ 21public 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 */ 45 static boolean bitEquals(double x, double y) { 46 return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); 47 } 48 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 */ 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 */ 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 */ 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 */ 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 */ 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 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 */ 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 */ 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 */ 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 */ 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 */ 195 public void testSerialization() throws Exception { 196 AtomicDouble a = new AtomicDouble(); 197 AtomicDouble b = serialClone(a); 198 assertTrue(a != b); 199 a.set(-22.0); 200 AtomicDouble c = serialClone(a); 201 assertBitEquals(-22.0, a.get()); 202 assertBitEquals(0.0, b.get()); 203 assertBitEquals(-22.0, c.get()); 204 for (double x : VALUES) { 205 AtomicDouble d = new AtomicDouble(x); 206 assertBitEquals(serialClone(d).get(), d.get()); 207 } 208 } 209 210 /** 211 * toString returns current value 212 */ 213 public void testToString() { 214 AtomicDouble at = new AtomicDouble(); 215 assertEquals("0.0", at.toString()); 216 for (double x : VALUES) { 217 at.set(x); 218 assertEquals(Double.toString(x), at.toString()); 219 } 220 } 221 222 /** 223 * intValue returns current value. 224 */ 225 public void testIntValue() { 226 AtomicDouble at = new AtomicDouble(); 227 assertEquals(0, at.intValue()); 228 for (double x : VALUES) { 229 at.set(x); 230 assertEquals((int) x, at.intValue()); 231 } 232 } 233 234 /** 235 * longValue returns current value. 236 */ 237 public void testLongValue() { 238 AtomicDouble at = new AtomicDouble(); 239 assertEquals(0L, at.longValue()); 240 for (double x : VALUES) { 241 at.set(x); 242 assertEquals((long) x, at.longValue()); 243 } 244 } 245 246 /** 247 * floatValue returns current value. 248 */ 249 public void testFloatValue() { 250 AtomicDouble at = new AtomicDouble(); 251 assertEquals(0.0f, at.floatValue()); 252 for (double x : VALUES) { 253 at.set(x); 254 assertEquals((float) x, at.floatValue()); 255 } 256 } 257 258 /** 259 * doubleValue returns current value. 260 */ 261 public void testDoubleValue() { 262 AtomicDouble at = new AtomicDouble(); 263 assertEquals(0.0d, at.doubleValue()); 264 for (double x : VALUES) { 265 at.set(x); 266 assertBitEquals(x, at.doubleValue()); 267 } 268 } 269 270 /** 271 * compareAndSet treats +0.0 and -0.0 as distinct values 272 */ 273 public void testDistinctZeros() { 274 AtomicDouble at = new AtomicDouble(+0.0); 275 assertFalse(at.compareAndSet(-0.0, 7.0)); 276 assertFalse(at.weakCompareAndSet(-0.0, 7.0)); 277 assertBitEquals(+0.0, at.get()); 278 assertTrue(at.compareAndSet(+0.0, -0.0)); 279 assertBitEquals(-0.0, at.get()); 280 assertFalse(at.compareAndSet(+0.0, 7.0)); 281 assertFalse(at.weakCompareAndSet(+0.0, 7.0)); 282 assertBitEquals(-0.0, at.get()); 283 } 284} 285