| /* |
| * Written by Doug Lea and Martin Buchholz with assistance from |
| * members of JCP JSR-166 Expert Group and released to the public |
| * domain, as explained at |
| * http://creativecommons.org/publicdomain/zero/1.0/ |
| */ |
| |
| /* |
| * Source: |
| * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/test/tck-jsr166e/AtomicDoubleTest.java?revision=1.8 |
| * (Modified to adapt to guava coding conventions) |
| */ |
| |
| package com.google.common.util.concurrent; |
| |
| import junit.framework.*; |
| |
| /** |
| * Unit test for {@link AtomicDouble}. |
| */ |
| public class AtomicDoubleTest extends JSR166TestCase { |
| |
| private static final double[] VALUES = { |
| Double.NEGATIVE_INFINITY, |
| -Double.MAX_VALUE, |
| (double) Long.MIN_VALUE, |
| (double) Integer.MIN_VALUE, |
| -Math.PI, |
| -1.0, |
| -Double.MIN_VALUE, |
| -0.0, |
| +0.0, |
| Double.MIN_VALUE, |
| 1.0, |
| Math.PI, |
| (double) Integer.MAX_VALUE, |
| (double) Long.MAX_VALUE, |
| Double.MAX_VALUE, |
| Double.POSITIVE_INFINITY, |
| Double.NaN, |
| Float.MAX_VALUE, |
| }; |
| |
| /** The notion of equality used by AtomicDouble */ |
| static boolean bitEquals(double x, double y) { |
| return Double.doubleToRawLongBits(x) == Double.doubleToRawLongBits(y); |
| } |
| |
| static void assertBitEquals(double x, double y) { |
| assertEquals(Double.doubleToRawLongBits(x), |
| Double.doubleToRawLongBits(y)); |
| } |
| |
| /** |
| * constructor initializes to given value |
| */ |
| public void testConstructor() { |
| for (double x : VALUES) { |
| AtomicDouble a = new AtomicDouble(x); |
| assertBitEquals(x, a.get()); |
| } |
| } |
| |
| /** |
| * default constructed initializes to zero |
| */ |
| public void testConstructor2() { |
| AtomicDouble a = new AtomicDouble(); |
| assertBitEquals(0.0, a.get()); |
| } |
| |
| /** |
| * get returns the last value set |
| */ |
| public void testGetSet() { |
| AtomicDouble at = new AtomicDouble(1.0); |
| assertBitEquals(1.0, at.get()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertBitEquals(x, at.get()); |
| } |
| } |
| |
| /** |
| * get returns the last value lazySet in same thread |
| */ |
| public void testGetLazySet() { |
| AtomicDouble at = new AtomicDouble(1.0); |
| assertBitEquals(1.0, at.get()); |
| for (double x : VALUES) { |
| at.lazySet(x); |
| assertBitEquals(x, at.get()); |
| } |
| } |
| |
| /** |
| * compareAndSet succeeds in changing value if equal to expected else fails |
| */ |
| public void testCompareAndSet() { |
| double prev = Math.E; |
| double unused = Math.E + Math.PI; |
| AtomicDouble at = new AtomicDouble(prev); |
| for (double x : VALUES) { |
| assertBitEquals(prev, at.get()); |
| assertFalse(at.compareAndSet(unused, x)); |
| assertBitEquals(prev, at.get()); |
| assertTrue(at.compareAndSet(prev, x)); |
| assertBitEquals(x, at.get()); |
| prev = x; |
| } |
| } |
| |
| /** |
| * compareAndSet in one thread enables another waiting for value |
| * to succeed |
| */ |
| |
| public void testCompareAndSetInMultipleThreads() throws Exception { |
| final AtomicDouble at = new AtomicDouble(1.0); |
| Thread t = newStartedThread(new CheckedRunnable() { |
| public void realRun() { |
| while (!at.compareAndSet(2.0, 3.0)) { |
| Thread.yield(); |
| } |
| }}); |
| |
| assertTrue(at.compareAndSet(1.0, 2.0)); |
| awaitTermination(t); |
| assertBitEquals(3.0, at.get()); |
| } |
| |
| /** |
| * repeated weakCompareAndSet succeeds in changing value when equal |
| * to expected |
| */ |
| public void testWeakCompareAndSet() { |
| double prev = Math.E; |
| double unused = Math.E + Math.PI; |
| AtomicDouble at = new AtomicDouble(prev); |
| for (double x : VALUES) { |
| assertBitEquals(prev, at.get()); |
| assertFalse(at.weakCompareAndSet(unused, x)); |
| assertBitEquals(prev, at.get()); |
| while (!at.weakCompareAndSet(prev, x)) { |
| ; |
| } |
| assertBitEquals(x, at.get()); |
| prev = x; |
| } |
| } |
| |
| /** |
| * getAndSet returns previous value and sets to given value |
| */ |
| public void testGetAndSet() { |
| double prev = Math.E; |
| AtomicDouble at = new AtomicDouble(prev); |
| for (double x : VALUES) { |
| assertBitEquals(prev, at.getAndSet(x)); |
| prev = x; |
| } |
| } |
| |
| /** |
| * getAndAdd returns previous value and adds given value |
| */ |
| public void testGetAndAdd() { |
| for (double x : VALUES) { |
| for (double y : VALUES) { |
| AtomicDouble a = new AtomicDouble(x); |
| double z = a.getAndAdd(y); |
| assertBitEquals(x, z); |
| assertBitEquals(x + y, a.get()); |
| } |
| } |
| } |
| |
| /** |
| * addAndGet adds given value to current, and returns current value |
| */ |
| public void testAddAndGet() { |
| for (double x : VALUES) { |
| for (double y : VALUES) { |
| AtomicDouble a = new AtomicDouble(x); |
| double z = a.addAndGet(y); |
| assertBitEquals(x + y, z); |
| assertBitEquals(x + y, a.get()); |
| } |
| } |
| } |
| |
| /** |
| * a deserialized serialized atomic holds same value |
| */ |
| public void testSerialization() throws Exception { |
| AtomicDouble a = new AtomicDouble(); |
| AtomicDouble b = serialClone(a); |
| assertNotSame(a, b); |
| a.set(-22.0); |
| AtomicDouble c = serialClone(a); |
| assertNotSame(b, c); |
| assertBitEquals(-22.0, a.get()); |
| assertBitEquals(0.0, b.get()); |
| assertBitEquals(-22.0, c.get()); |
| for (double x : VALUES) { |
| AtomicDouble d = new AtomicDouble(x); |
| assertBitEquals(serialClone(d).get(), d.get()); |
| } |
| } |
| |
| /** |
| * toString returns current value |
| */ |
| public void testToString() { |
| AtomicDouble at = new AtomicDouble(); |
| assertEquals("0.0", at.toString()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertEquals(Double.toString(x), at.toString()); |
| } |
| } |
| |
| /** |
| * intValue returns current value. |
| */ |
| public void testIntValue() { |
| AtomicDouble at = new AtomicDouble(); |
| assertEquals(0, at.intValue()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertEquals((int) x, at.intValue()); |
| } |
| } |
| |
| /** |
| * longValue returns current value. |
| */ |
| public void testLongValue() { |
| AtomicDouble at = new AtomicDouble(); |
| assertEquals(0L, at.longValue()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertEquals((long) x, at.longValue()); |
| } |
| } |
| |
| /** |
| * floatValue returns current value. |
| */ |
| public void testFloatValue() { |
| AtomicDouble at = new AtomicDouble(); |
| assertEquals(0.0f, at.floatValue()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertEquals((float) x, at.floatValue()); |
| } |
| } |
| |
| /** |
| * doubleValue returns current value. |
| */ |
| public void testDoubleValue() { |
| AtomicDouble at = new AtomicDouble(); |
| assertEquals(0.0d, at.doubleValue()); |
| for (double x : VALUES) { |
| at.set(x); |
| assertBitEquals(x, at.doubleValue()); |
| } |
| } |
| |
| /** |
| * compareAndSet treats +0.0 and -0.0 as distinct values |
| */ |
| public void testDistinctZeros() { |
| AtomicDouble at = new AtomicDouble(+0.0); |
| assertFalse(at.compareAndSet(-0.0, 7.0)); |
| assertFalse(at.weakCompareAndSet(-0.0, 7.0)); |
| assertBitEquals(+0.0, at.get()); |
| assertTrue(at.compareAndSet(+0.0, -0.0)); |
| assertBitEquals(-0.0, at.get()); |
| assertFalse(at.compareAndSet(+0.0, 7.0)); |
| assertFalse(at.weakCompareAndSet(+0.0, 7.0)); |
| assertBitEquals(-0.0, at.get()); |
| } |
| } |