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