Advertisement
Sk8erPeter

AtomicLong.java (JDK 1.8.0_05)

May 25th, 2014
370
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 10.32 KB | None | 0 0
  1. /*
  2.  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  3.  *
  4.  *
  5.  *
  6.  *
  7.  *
  8.  *
  9.  *
  10.  *
  11.  *
  12.  *
  13.  *
  14.  *
  15.  *
  16.  *
  17.  *
  18.  *
  19.  *
  20.  *
  21.  *
  22.  *
  23.  */
  24.  
  25. /*
  26.  *
  27.  *
  28.  *
  29.  *
  30.  *
  31.  * Written by Doug Lea with assistance from members of JCP JSR-166
  32.  * Expert Group and released to the public domain, as explained at
  33.  * http://creativecommons.org/publicdomain/zero/1.0/
  34.  */
  35.  
  36. package java.util.concurrent.atomic;
  37. import java.util.function.LongUnaryOperator;
  38. import java.util.function.LongBinaryOperator;
  39. import sun.misc.Unsafe;
  40.  
  41. /**
  42.  * A {@code long} value that may be updated atomically.  See the
  43.  * {@link java.util.concurrent.atomic} package specification for
  44.  * description of the properties of atomic variables. An
  45.  * {@code AtomicLong} is used in applications such as atomically
  46.  * incremented sequence numbers, and cannot be used as a replacement
  47.  * for a {@link java.lang.Long}. However, this class does extend
  48.  * {@code Number} to allow uniform access by tools and utilities that
  49.  * deal with numerically-based classes.
  50.  *
  51.  * @since 1.5
  52.  * @author Doug Lea
  53.  */
  54. public class AtomicLong extends Number implements java.io.Serializable {
  55.     private static final long serialVersionUID = 1927816293512124184L;
  56.  
  57.     // setup to use Unsafe.compareAndSwapLong for updates
  58.     private static final Unsafe unsafe = Unsafe.getUnsafe();
  59.     private static final long valueOffset;
  60.  
  61.     /**
  62.      * Records whether the underlying JVM supports lockless
  63.      * compareAndSwap for longs. While the Unsafe.compareAndSwapLong
  64.      * method works in either case, some constructions should be
  65.      * handled at Java level to avoid locking user-visible locks.
  66.      */
  67.     static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
  68.  
  69.     /**
  70.      * Returns whether underlying JVM supports lockless CompareAndSet
  71.      * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
  72.      */
  73.     private static native boolean VMSupportsCS8();
  74.  
  75.     static {
  76.         try {
  77.             valueOffset = unsafe.objectFieldOffset
  78.                 (AtomicLong.class.getDeclaredField("value"));
  79.         } catch (Exception ex) { throw new Error(ex); }
  80.     }
  81.  
  82.     private volatile long value;
  83.  
  84.     /**
  85.      * Creates a new AtomicLong with the given initial value.
  86.      *
  87.      * @param initialValue the initial value
  88.      */
  89.     public AtomicLong(long initialValue) {
  90.         value = initialValue;
  91.     }
  92.  
  93.     /**
  94.      * Creates a new AtomicLong with initial value {@code 0}.
  95.      */
  96.     public AtomicLong() {
  97.     }
  98.  
  99.     /**
  100.      * Gets the current value.
  101.      *
  102.      * @return the current value
  103.      */
  104.     public final long get() {
  105.         return value;
  106.     }
  107.  
  108.     /**
  109.      * Sets to the given value.
  110.      *
  111.      * @param newValue the new value
  112.      */
  113.     public final void set(long newValue) {
  114.         value = newValue;
  115.     }
  116.  
  117.     /**
  118.      * Eventually sets to the given value.
  119.      *
  120.      * @param newValue the new value
  121.      * @since 1.6
  122.      */
  123.     public final void lazySet(long newValue) {
  124.         unsafe.putOrderedLong(this, valueOffset, newValue);
  125.     }
  126.  
  127.     /**
  128.      * Atomically sets to the given value and returns the old value.
  129.      *
  130.      * @param newValue the new value
  131.      * @return the previous value
  132.      */
  133.     public final long getAndSet(long newValue) {
  134.         return unsafe.getAndSetLong(this, valueOffset, newValue);
  135.     }
  136.  
  137.     /**
  138.      * Atomically sets the value to the given updated value
  139.      * if the current value {@code ==} the expected value.
  140.      *
  141.      * @param expect the expected value
  142.      * @param update the new value
  143.      * @return {@code true} if successful. False return indicates that
  144.      * the actual value was not equal to the expected value.
  145.      */
  146.     public final boolean compareAndSet(long expect, long update) {
  147.         return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
  148.     }
  149.  
  150.     /**
  151.      * Atomically sets the value to the given updated value
  152.      * if the current value {@code ==} the expected value.
  153.      *
  154.      * <p><a href="package-summary.html#weakCompareAndSet">May fail
  155.      * spuriously and does not provide ordering guarantees</a>, so is
  156.      * only rarely an appropriate alternative to {@code compareAndSet}.
  157.      *
  158.      * @param expect the expected value
  159.      * @param update the new value
  160.      * @return {@code true} if successful
  161.      */
  162.     public final boolean weakCompareAndSet(long expect, long update) {
  163.         return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
  164.     }
  165.  
  166.     /**
  167.      * Atomically increments by one the current value.
  168.      *
  169.      * @return the previous value
  170.      */
  171.     public final long getAndIncrement() {
  172.         return unsafe.getAndAddLong(this, valueOffset, 1L);
  173.     }
  174.  
  175.     /**
  176.      * Atomically decrements by one the current value.
  177.      *
  178.      * @return the previous value
  179.      */
  180.     public final long getAndDecrement() {
  181.         return unsafe.getAndAddLong(this, valueOffset, -1L);
  182.     }
  183.  
  184.     /**
  185.      * Atomically adds the given value to the current value.
  186.      *
  187.      * @param delta the value to add
  188.      * @return the previous value
  189.      */
  190.     public final long getAndAdd(long delta) {
  191.         return unsafe.getAndAddLong(this, valueOffset, delta);
  192.     }
  193.  
  194.     /**
  195.      * Atomically increments by one the current value.
  196.      *
  197.      * @return the updated value
  198.      */
  199.     public final long incrementAndGet() {
  200.         return unsafe.getAndAddLong(this, valueOffset, 1L) + 1L;
  201.     }
  202.  
  203.     /**
  204.      * Atomically decrements by one the current value.
  205.      *
  206.      * @return the updated value
  207.      */
  208.     public final long decrementAndGet() {
  209.         return unsafe.getAndAddLong(this, valueOffset, -1L) - 1L;
  210.     }
  211.  
  212.     /**
  213.      * Atomically adds the given value to the current value.
  214.      *
  215.      * @param delta the value to add
  216.      * @return the updated value
  217.      */
  218.     public final long addAndGet(long delta) {
  219.         return unsafe.getAndAddLong(this, valueOffset, delta) + delta;
  220.     }
  221.  
  222.     /**
  223.      * Atomically updates the current value with the results of
  224.      * applying the given function, returning the previous value. The
  225.      * function should be side-effect-free, since it may be re-applied
  226.      * when attempted updates fail due to contention among threads.
  227.      *
  228.      * @param updateFunction a side-effect-free function
  229.      * @return the previous value
  230.      * @since 1.8
  231.      */
  232.     public final long getAndUpdate(LongUnaryOperator updateFunction) {
  233.         long prev, next;
  234.         do {
  235.             prev = get();
  236.             next = updateFunction.applyAsLong(prev);
  237.         } while (!compareAndSet(prev, next));
  238.         return prev;
  239.     }
  240.  
  241.     /**
  242.      * Atomically updates the current value with the results of
  243.      * applying the given function, returning the updated value. The
  244.      * function should be side-effect-free, since it may be re-applied
  245.      * when attempted updates fail due to contention among threads.
  246.      *
  247.      * @param updateFunction a side-effect-free function
  248.      * @return the updated value
  249.      * @since 1.8
  250.      */
  251.     public final long updateAndGet(LongUnaryOperator updateFunction) {
  252.         long prev, next;
  253.         do {
  254.             prev = get();
  255.             next = updateFunction.applyAsLong(prev);
  256.         } while (!compareAndSet(prev, next));
  257.         return next;
  258.     }
  259.  
  260.     /**
  261.      * Atomically updates the current value with the results of
  262.      * applying the given function to the current and given values,
  263.      * returning the previous value. The function should be
  264.      * side-effect-free, since it may be re-applied when attempted
  265.      * updates fail due to contention among threads.  The function
  266.      * is applied with the current value as its first argument,
  267.      * and the given update as the second argument.
  268.      *
  269.      * @param x the update value
  270.      * @param accumulatorFunction a side-effect-free function of two arguments
  271.      * @return the previous value
  272.      * @since 1.8
  273.      */
  274.     public final long getAndAccumulate(long x,
  275.                                        LongBinaryOperator accumulatorFunction) {
  276.         long prev, next;
  277.         do {
  278.             prev = get();
  279.             next = accumulatorFunction.applyAsLong(prev, x);
  280.         } while (!compareAndSet(prev, next));
  281.         return prev;
  282.     }
  283.  
  284.     /**
  285.      * Atomically updates the current value with the results of
  286.      * applying the given function to the current and given values,
  287.      * returning the updated value. The function should be
  288.      * side-effect-free, since it may be re-applied when attempted
  289.      * updates fail due to contention among threads.  The function
  290.      * is applied with the current value as its first argument,
  291.      * and the given update as the second argument.
  292.      *
  293.      * @param x the update value
  294.      * @param accumulatorFunction a side-effect-free function of two arguments
  295.      * @return the updated value
  296.      * @since 1.8
  297.      */
  298.     public final long accumulateAndGet(long x,
  299.                                        LongBinaryOperator accumulatorFunction) {
  300.         long prev, next;
  301.         do {
  302.             prev = get();
  303.             next = accumulatorFunction.applyAsLong(prev, x);
  304.         } while (!compareAndSet(prev, next));
  305.         return next;
  306.     }
  307.  
  308.     /**
  309.      * Returns the String representation of the current value.
  310.      * @return the String representation of the current value
  311.      */
  312.     public String toString() {
  313.         return Long.toString(get());
  314.     }
  315.  
  316.     /**
  317.      * Returns the value of this {@code AtomicLong} as an {@code int}
  318.      * after a narrowing primitive conversion.
  319.      * @jls 5.1.3 Narrowing Primitive Conversions
  320.      */
  321.     public int intValue() {
  322.         return (int)get();
  323.     }
  324.  
  325.     /**
  326.      * Returns the value of this {@code AtomicLong} as a {@code long}.
  327.      */
  328.     public long longValue() {
  329.         return get();
  330.     }
  331.  
  332.     /**
  333.      * Returns the value of this {@code AtomicLong} as a {@code float}
  334.      * after a widening primitive conversion.
  335.      * @jls 5.1.2 Widening Primitive Conversions
  336.      */
  337.     public float floatValue() {
  338.         return (float)get();
  339.     }
  340.  
  341.     /**
  342.      * Returns the value of this {@code AtomicLong} as a {@code double}
  343.      * after a widening primitive conversion.
  344.      * @jls 5.1.2 Widening Primitive Conversions
  345.      */
  346.     public double doubleValue() {
  347.         return (double)get();
  348.     }
  349.  
  350. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement