11d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
21d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Written by Doug Lea with assistance from members of JCP JSR-166
31d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Expert Group and released to the public domain, as explained at
41d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://creativecommons.org/publicdomain/zero/1.0/
51d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
61d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
71d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/*
81d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * Source:
91d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/extra/AtomicDoubleArray.java?revision=1.5
101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * (Modified to adapt to guava coding conventions and
111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * to use AtomicLongArray instead of sun.misc.Unsafe)
121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpackage com.google.common.util.concurrent;
151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport com.google.common.annotations.Beta;
171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.lang.Double.doubleToRawLongBits;
191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport static java.lang.Double.longBitsToDouble;
201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertimport java.util.concurrent.atomic.AtomicLongArray;
211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert/**
231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * A {@code double} array in which elements may be updated atomically.
241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * See the {@link java.util.concurrent.atomic} package specification
251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * for description of the properties of atomic variables.
261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * <p><a name="bitEquals">This class compares primitive {@code double}
281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * values in methods such as {@link #compareAndSet} by comparing their
291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * bitwise representation using {@link Double#doubleToRawLongBits},
301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * which differs from both the primitive double {@code ==} operator
311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * and from {@link Double#equals}, as if implemented by:
321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *  <pre> {@code
331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * static boolean bitEquals(double x, double y) {
341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   long xBits = Double.doubleToRawLongBits(x);
351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   long yBits = Double.doubleToRawLongBits(y);
361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *   return xBits == yBits;
371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * }}</pre>
381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert *
391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Doug Lea
401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @author Martin Buchholz
411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert * @since 11.0
421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert */
431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert@Beta
441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringertpublic class AtomicDoubleArray implements java.io.Serializable {
451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private static final long serialVersionUID = 0L;
461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Making this non-final is the lesser evil according to Effective
481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  // Java 2nd Edition Item 76: Write readObject methods defensively.
491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private transient AtomicLongArray longs;
501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code AtomicDoubleArray} of the given length,
531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * with all elements initially zero.
541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param length the length of the array
561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public AtomicDoubleArray(int length) {
581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.longs = new AtomicLongArray(length);
591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Creates a new {@code AtomicDoubleArray} with the same length
631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * as, and all elements copied from, the given array.
641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param array the array to copy elements from
661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @throws NullPointerException if array is null
671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public AtomicDoubleArray(double[] array) {
691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    final int len = array.length;
701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long[] longArray = new long[len];
711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < len; i++) {
721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      longArray[i] = doubleToRawLongBits(array[i]);
731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.longs = new AtomicLongArray(longArray);
751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the length of the array.
791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the length of the array
811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final int length() {
831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return longs.length();
841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Gets the current value at position {@code i}.
881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the current value
911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final double get(int i) {
931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return longBitsToDouble(longs.get(i));
941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Sets the element at position {@code i} to the given value.
981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param newValue the new value
1011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final void set(int i, double newValue) {
1031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long next = doubleToRawLongBits(newValue);
1041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    longs.set(i, next);
1051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Eventually sets the element at position {@code i} to the given value.
1091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param newValue the new value
1121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final void lazySet(int i, double newValue) {
1141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    set(i, newValue);
1151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // TODO(user): replace with code below when jdk5 support is dropped.
1161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // long next = doubleToRawLongBits(newValue);
1171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // longs.lazySet(i, next);
1181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Atomically sets the element at position {@code i} to the given value
1221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * and returns the old value.
1231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param newValue the new value
1261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the previous value
1271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final double getAndSet(int i, double newValue) {
1291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    long next = doubleToRawLongBits(newValue);
1301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return longBitsToDouble(longs.getAndSet(i, next));
1311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Atomically sets the element at position {@code i} to the given
1351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * updated value
1361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * if the current value is <a href="#bitEquals">bitwise equal</a>
1371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to the expected value.
1381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param expect the expected value
1411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param update the new value
1421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return true if successful. False return indicates that
1431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * the actual value was not equal to the expected value.
1441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final boolean compareAndSet(int i, double expect, double update) {
1461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return longs.compareAndSet(i,
1471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                               doubleToRawLongBits(expect),
1481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                               doubleToRawLongBits(update));
1491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Atomically sets the element at position {@code i} to the given
1531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * updated value
1541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * if the current value is <a href="#bitEquals">bitwise equal</a>
1551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * to the expected value.
1561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * <p>May <a
1581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * href="http://download.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html#Spurious">
1591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * fail spuriously</a>
1601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * and does not provide ordering guarantees, so is only rarely an
1611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * appropriate alternative to {@code compareAndSet}.
1621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param expect the expected value
1651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param update the new value
1661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return true if successful
1671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final boolean weakCompareAndSet(int i, double expect, double update) {
1691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    return longs.weakCompareAndSet(i,
1701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                                   doubleToRawLongBits(expect),
1711d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert                                   doubleToRawLongBits(update));
1721d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1731d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1741d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1751d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Atomically adds the given value to the element at index {@code i}.
1761d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1771d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1781d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delta the value to add
1791d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the previous value
1801d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
1811d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public final double getAndAdd(int i, double delta) {
1821d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (true) {
1831d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      long current = longs.get(i);
1841d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      double currentVal = longBitsToDouble(current);
1851d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      double nextVal = currentVal + delta;
1861d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      long next = doubleToRawLongBits(nextVal);
1871d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (longs.compareAndSet(i, current, next)) {
1881d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return currentVal;
1891d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
1901d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
1911d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
1921d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
1931d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
1941d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Atomically adds the given value to the element at index {@code i}.
1951d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
1961d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param i the index
1971d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @param delta the value to add
1981d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the updated value
1991d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2001d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public double addAndGet(int i, double delta) {
2011d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    while (true) {
2021d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      long current = longs.get(i);
2031d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      double currentVal = longBitsToDouble(current);
2041d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      double nextVal = currentVal + delta;
2051d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      long next = doubleToRawLongBits(nextVal);
2061d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (longs.compareAndSet(i, current, next)) {
2071d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return nextVal;
2081d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2091d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2101d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2111d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2121d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2131d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Returns the String representation of the current values of array.
2141d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @return the String representation of the current values of array
2151d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2161d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  public String toString() {
2171d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int iMax = length() - 1;
2181d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    if (iMax == -1) {
2191d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      return "[]";
2201d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2211d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2221d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Double.toString(Math.PI).length() == 17
2231d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    StringBuilder b = new StringBuilder((17 + 2) * (iMax + 1));
2241d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    b.append('[');
2251d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0;; i++) {
2261d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      b.append(longBitsToDouble(longs.get(i)));
2271d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      if (i == iMax) {
2281d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert        return b.append(']').toString();
2291d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      }
2301d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      b.append(',').append(' ');
2311d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2321d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2331d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2341d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2351d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Saves the state to a stream (that is, serializes it).
2361d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *
2371d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * @serialData The length of the array is emitted (int), followed by all
2381d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   *             of its elements (each a {@code double}) in the proper order.
2391d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2401d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void writeObject(java.io.ObjectOutputStream s)
2411d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws java.io.IOException {
2421d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    s.defaultWriteObject();
2431d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2441d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Write out array length
2451d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int length = length();
2461d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    s.writeInt(length);
2471d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2481d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Write out all elements in the proper order.
2491d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < length; i++) {
2501d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      s.writeDouble(get(i));
2511d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2521d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2531d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2541d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  /**
2551d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   * Reconstitutes the instance from a stream (that is, deserializes it).
2561d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert   */
2571d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  private void readObject(java.io.ObjectInputStream s)
2581d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      throws java.io.IOException, ClassNotFoundException {
2591d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    s.defaultReadObject();
2601d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2611d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Read in array length and allocate array
2621d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    int length = s.readInt();
2631d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    this.longs = new AtomicLongArray(length);
2641d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert
2651d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    // Read in all elements in the proper order.
2661d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    for (int i = 0; i < length; i++) {
2671d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert      set(i, s.readDouble());
2681d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert    }
2691d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert  }
2701d580d0f6ee4f21eb309ba7b509d2c6d671c4044Bjorn Bringert}
271