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 17 /** Unit test for {@link AtomicDouble}. */ 18 public class AtomicDoubleTest extends JSR166TestCase { 19 20 private static final double[] VALUES = { 21 Double.NEGATIVE_INFINITY, 22 -Double.MAX_VALUE, 23 (double) Long.MIN_VALUE, 24 (double) Integer.MIN_VALUE, 25 -Math.PI, 26 -1.0, 27 -Double.MIN_VALUE, 28 -0.0, 29 +0.0, 30 Double.MIN_VALUE, 31 1.0, 32 Math.PI, 33 (double) Integer.MAX_VALUE, 34 (double) Long.MAX_VALUE, 35 Double.MAX_VALUE, 36 Double.POSITIVE_INFINITY, 37 Double.NaN, 38 Float.MAX_VALUE, 39 }; 40 41 /** The notion of equality used by AtomicDouble */ bitEquals(double x, double y)42 static boolean bitEquals(double x, double y) { 43 return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); 44 } 45 assertBitEquals(double x, double y)46 static void assertBitEquals(double x, double y) { 47 assertEquals(Double.doubleToRawLongBits(x), Double.doubleToRawLongBits(y)); 48 } 49 50 /** constructor initializes to given value */ testConstructor()51 public void testConstructor() { 52 for (double x : VALUES) { 53 AtomicDouble a = new AtomicDouble(x); 54 assertBitEquals(x, a.get()); 55 } 56 } 57 58 /** default constructed initializes to zero */ testConstructor2()59 public void testConstructor2() { 60 AtomicDouble a = new AtomicDouble(); 61 assertBitEquals(0.0, a.get()); 62 } 63 64 /** get returns the last value set */ testGetSet()65 public void testGetSet() { 66 AtomicDouble at = new AtomicDouble(1.0); 67 assertBitEquals(1.0, at.get()); 68 for (double x : VALUES) { 69 at.set(x); 70 assertBitEquals(x, at.get()); 71 } 72 } 73 74 /** get returns the last value lazySet in same thread */ testGetLazySet()75 public void testGetLazySet() { 76 AtomicDouble at = new AtomicDouble(1.0); 77 assertBitEquals(1.0, at.get()); 78 for (double x : VALUES) { 79 at.lazySet(x); 80 assertBitEquals(x, at.get()); 81 } 82 } 83 84 /** compareAndSet succeeds in changing value if equal to expected else fails */ testCompareAndSet()85 public void testCompareAndSet() { 86 double prev = Math.E; 87 double unused = Math.E + Math.PI; 88 AtomicDouble at = new AtomicDouble(prev); 89 for (double x : VALUES) { 90 assertBitEquals(prev, at.get()); 91 assertFalse(at.compareAndSet(unused, x)); 92 assertBitEquals(prev, at.get()); 93 assertTrue(at.compareAndSet(prev, x)); 94 assertBitEquals(x, at.get()); 95 prev = x; 96 } 97 } 98 99 /** compareAndSet in one thread enables another waiting for value to succeed */ 100 testCompareAndSetInMultipleThreads()101 public void testCompareAndSetInMultipleThreads() throws Exception { 102 final AtomicDouble at = new AtomicDouble(1.0); 103 Thread t = 104 newStartedThread( 105 new CheckedRunnable() { 106 @Override 107 public void realRun() { 108 while (!at.compareAndSet(2.0, 3.0)) { 109 Thread.yield(); 110 } 111 } 112 }); 113 114 assertTrue(at.compareAndSet(1.0, 2.0)); 115 awaitTermination(t); 116 assertBitEquals(3.0, at.get()); 117 } 118 119 /** repeated weakCompareAndSet succeeds in changing value when equal to expected */ testWeakCompareAndSet()120 public void testWeakCompareAndSet() { 121 double prev = Math.E; 122 double unused = Math.E + Math.PI; 123 AtomicDouble at = new AtomicDouble(prev); 124 for (double x : VALUES) { 125 assertBitEquals(prev, at.get()); 126 assertFalse(at.weakCompareAndSet(unused, x)); 127 assertBitEquals(prev, at.get()); 128 while (!at.weakCompareAndSet(prev, x)) {; 129 } 130 assertBitEquals(x, at.get()); 131 prev = x; 132 } 133 } 134 135 /** getAndSet returns previous value and sets to given value */ testGetAndSet()136 public void testGetAndSet() { 137 double prev = Math.E; 138 AtomicDouble at = new AtomicDouble(prev); 139 for (double x : VALUES) { 140 assertBitEquals(prev, at.getAndSet(x)); 141 prev = x; 142 } 143 } 144 145 /** getAndAdd returns previous value and adds given value */ testGetAndAdd()146 public void testGetAndAdd() { 147 for (double x : VALUES) { 148 for (double y : VALUES) { 149 AtomicDouble a = new AtomicDouble(x); 150 double z = a.getAndAdd(y); 151 assertBitEquals(x, z); 152 assertBitEquals(x + y, a.get()); 153 } 154 } 155 } 156 157 /** addAndGet adds given value to current, and returns current value */ testAddAndGet()158 public void testAddAndGet() { 159 for (double x : VALUES) { 160 for (double y : VALUES) { 161 AtomicDouble a = new AtomicDouble(x); 162 double z = a.addAndGet(y); 163 assertBitEquals(x + y, z); 164 assertBitEquals(x + y, a.get()); 165 } 166 } 167 } 168 169 /** a deserialized serialized atomic holds same value */ testSerialization()170 public void testSerialization() throws Exception { 171 AtomicDouble a = new AtomicDouble(); 172 AtomicDouble b = serialClone(a); 173 assertNotSame(a, b); 174 a.set(-22.0); 175 AtomicDouble c = serialClone(a); 176 assertNotSame(b, c); 177 assertBitEquals(-22.0, a.get()); 178 assertBitEquals(0.0, b.get()); 179 assertBitEquals(-22.0, c.get()); 180 for (double x : VALUES) { 181 AtomicDouble d = new AtomicDouble(x); 182 assertBitEquals(serialClone(d).get(), d.get()); 183 } 184 } 185 186 /** toString returns current value */ testToString()187 public void testToString() { 188 AtomicDouble at = new AtomicDouble(); 189 assertEquals("0.0", at.toString()); 190 for (double x : VALUES) { 191 at.set(x); 192 assertEquals(Double.toString(x), at.toString()); 193 } 194 } 195 196 /** intValue returns current value. */ testIntValue()197 public void testIntValue() { 198 AtomicDouble at = new AtomicDouble(); 199 assertEquals(0, at.intValue()); 200 for (double x : VALUES) { 201 at.set(x); 202 assertEquals((int) x, at.intValue()); 203 } 204 } 205 206 /** longValue returns current value. */ testLongValue()207 public void testLongValue() { 208 AtomicDouble at = new AtomicDouble(); 209 assertEquals(0L, at.longValue()); 210 for (double x : VALUES) { 211 at.set(x); 212 assertEquals((long) x, at.longValue()); 213 } 214 } 215 216 /** floatValue returns current value. */ testFloatValue()217 public void testFloatValue() { 218 AtomicDouble at = new AtomicDouble(); 219 assertEquals(0.0f, at.floatValue()); 220 for (double x : VALUES) { 221 at.set(x); 222 assertEquals((float) x, at.floatValue()); 223 } 224 } 225 226 /** doubleValue returns current value. */ testDoubleValue()227 public void testDoubleValue() { 228 AtomicDouble at = new AtomicDouble(); 229 assertEquals(0.0d, at.doubleValue()); 230 for (double x : VALUES) { 231 at.set(x); 232 assertBitEquals(x, at.doubleValue()); 233 } 234 } 235 236 /** compareAndSet treats +0.0 and -0.0 as distinct values */ testDistinctZeros()237 public void testDistinctZeros() { 238 AtomicDouble at = new AtomicDouble(+0.0); 239 assertFalse(at.compareAndSet(-0.0, 7.0)); 240 assertFalse(at.weakCompareAndSet(-0.0, 7.0)); 241 assertBitEquals(+0.0, at.get()); 242 assertTrue(at.compareAndSet(+0.0, -0.0)); 243 assertBitEquals(-0.0, at.get()); 244 assertFalse(at.compareAndSet(+0.0, 7.0)); 245 assertFalse(at.weakCompareAndSet(+0.0, 7.0)); 246 assertBitEquals(-0.0, at.get()); 247 } 248 } 249