Home | History | Annotate | Download | only in concurrent
      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 */
     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     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    */
    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    */
    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    */
    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    */
    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    */
    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    */
    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