1. /*
  2. * @(#)AtomicInteger.java 1.5 04/01/12
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package java.util.concurrent.atomic;
  8. import sun.misc.Unsafe;
  9. /**
  10. * An <tt>int</tt> value that may be updated atomically. See the
  11. * {@link java.util.concurrent.atomic} package specification for
  12. * description of the properties of atomic variables. An
  13. * <tt>AtomicInteger</tt> is used in applications such as atomically
  14. * incremented counters, and cannot be used as a replacement for an
  15. * {@link java.lang.Integer}. However, this class does extend
  16. * <tt>Number</tt> to allow uniform access by tools and utilities that
  17. * deal with numerically-based classes.
  18. *
  19. *
  20. * @since 1.5
  21. * @author Doug Lea
  22. */
  23. public class AtomicInteger extends Number implements java.io.Serializable {
  24. private static final long serialVersionUID = 6214790243416807050L;
  25. // setup to use Unsafe.compareAndSwapInt for updates
  26. private static final Unsafe unsafe = Unsafe.getUnsafe();
  27. private static final long valueOffset;
  28. static {
  29. try {
  30. valueOffset = unsafe.objectFieldOffset
  31. (AtomicInteger.class.getDeclaredField("value"));
  32. } catch(Exception ex) { throw new Error(ex); }
  33. }
  34. private volatile int value;
  35. /**
  36. * Create a new AtomicInteger with the given initial value.
  37. *
  38. * @param initialValue the initial value
  39. */
  40. public AtomicInteger(int initialValue) {
  41. value = initialValue;
  42. }
  43. /**
  44. * Create a new AtomicInteger with initial value <tt>0</tt>.
  45. */
  46. public AtomicInteger() {
  47. }
  48. /**
  49. * Get the current value.
  50. *
  51. * @return the current value
  52. */
  53. public final int get() {
  54. return value;
  55. }
  56. /**
  57. * Set to the given value.
  58. *
  59. * @param newValue the new value
  60. */
  61. public final void set(int newValue) {
  62. value = newValue;
  63. }
  64. /**
  65. * Set to the give value and return the old value.
  66. *
  67. * @param newValue the new value
  68. * @return the previous value
  69. */
  70. public final int getAndSet(int newValue) {
  71. for (;;) {
  72. int current = get();
  73. if (compareAndSet(current, newValue))
  74. return current;
  75. }
  76. }
  77. /**
  78. * Atomically set the value to the given updated value
  79. * if the current value <tt>==</tt> the expected value.
  80. * @param expect the expected value
  81. * @param update the new value
  82. * @return true if successful. False return indicates that
  83. * the actual value was not equal to the expected value.
  84. */
  85. public final boolean compareAndSet(int expect, int update) {
  86. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  87. }
  88. /**
  89. * Atomically set the value to the given updated value
  90. * if the current value <tt>==</tt> the expected value.
  91. * May fail spuriously.
  92. * @param expect the expected value
  93. * @param update the new value
  94. * @return true if successful.
  95. */
  96. public final boolean weakCompareAndSet(int expect, int update) {
  97. return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
  98. }
  99. /**
  100. * Atomically increment by one the current value.
  101. * @return the previous value
  102. */
  103. public final int getAndIncrement() {
  104. for (;;) {
  105. int current = get();
  106. int next = current + 1;
  107. if (compareAndSet(current, next))
  108. return current;
  109. }
  110. }
  111. /**
  112. * Atomically decrement by one the current value.
  113. * @return the previous value
  114. */
  115. public final int getAndDecrement() {
  116. for (;;) {
  117. int current = get();
  118. int next = current - 1;
  119. if (compareAndSet(current, next))
  120. return current;
  121. }
  122. }
  123. /**
  124. * Atomically add the given value to current value.
  125. * @param delta the value to add
  126. * @return the previous value
  127. */
  128. public final int getAndAdd(int delta) {
  129. for (;;) {
  130. int current = get();
  131. int next = current + delta;
  132. if (compareAndSet(current, next))
  133. return current;
  134. }
  135. }
  136. /**
  137. * Atomically increment by one the current value.
  138. * @return the updated value
  139. */
  140. public final int incrementAndGet() {
  141. for (;;) {
  142. int current = get();
  143. int next = current + 1;
  144. if (compareAndSet(current, next))
  145. return next;
  146. }
  147. }
  148. /**
  149. * Atomically decrement by one the current value.
  150. * @return the updated value
  151. */
  152. public final int decrementAndGet() {
  153. for (;;) {
  154. int current = get();
  155. int next = current - 1;
  156. if (compareAndSet(current, next))
  157. return next;
  158. }
  159. }
  160. /**
  161. * Atomically add the given value to current value.
  162. * @param delta the value to add
  163. * @return the updated value
  164. */
  165. public final int addAndGet(int delta) {
  166. for (;;) {
  167. int current = get();
  168. int next = current + delta;
  169. if (compareAndSet(current, next))
  170. return next;
  171. }
  172. }
  173. /**
  174. * Returns the String representation of the current value.
  175. * @return the String representation of the current value.
  176. */
  177. public String toString() {
  178. return Integer.toString(get());
  179. }
  180. public int intValue() {
  181. return get();
  182. }
  183. public long longValue() {
  184. return (long)get();
  185. }
  186. public float floatValue() {
  187. return (float)get();
  188. }
  189. public double doubleValue() {
  190. return (double)get();
  191. }
  192. }