KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > java > util > concurrent > atomic > AtomicLong


1 /*
2  * @(#)AtomicLong.java 1.6 04/02/13
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package java.util.concurrent.atomic;
9 import sun.misc.Unsafe;
10
11 /**
12  * A <tt>long</tt> value that may be updated atomically. See the
13  * {@link java.util.concurrent.atomic} package specification for
14  * description of the properties of atomic variables. An
15  * <tt>AtomicLong</tt> is used in applications such as atomically
16  * incremented sequence numbers, and cannot be used as a replacement
17  * for a {@link java.lang.Long}. However, this class does extend
18  * <tt>Number</tt> to allow uniform access by tools and utilities that
19  * deal with numerically-based classes.
20  *
21  * @since 1.5
22  * @author Doug Lea
23  */

24 public class AtomicLong extends Number JavaDoc implements java.io.Serializable JavaDoc {
25     private static final long serialVersionUID = 1927816293512124184L;
26
27     // setup to use Unsafe.compareAndSwapLong for updates
28
private static final Unsafe unsafe = Unsafe.getUnsafe();
29     private static final long valueOffset;
30
31     /**
32      * Record whether the underlying JVM supports lockless
33      * CompareAndSet for longs. While the unsafe.CompareAndSetLong
34      * method works in either case, some constructions should be
35      * handled at Java level to avoid locking user-visible locks.
36      */

37     static final boolean VM_SUPPORTS_LONG_CAS = VMSupportsCS8();
38
39     /**
40      * Returns whether underlying JVM supports lockless CompareAndSet
41      * for longs. Called only once and cached in VM_SUPPORTS_LONG_CAS.
42      */

43     private static native boolean VMSupportsCS8();
44
45     static {
46       try {
47         valueOffset = unsafe.objectFieldOffset
48             (AtomicLong JavaDoc.class.getDeclaredField("value"));
49       } catch(Exception JavaDoc ex) { throw new Error JavaDoc(ex); }
50     }
51
52     private volatile long value;
53
54     /**
55      * Create a new AtomicLong with the given initial value.
56      *
57      * @param initialValue the initial value
58      */

59     public AtomicLong(long initialValue) {
60         value = initialValue;
61     }
62
63     /**
64      * Create a new AtomicLong with initial value <tt>0</tt>.
65      */

66     public AtomicLong() {
67     }
68   
69     /**
70      * Get the current value.
71      *
72      * @return the current value
73      */

74     public final long get() {
75         return value;
76     }
77  
78     /**
79      * Set to the given value.
80      *
81      * @param newValue the new value
82      */

83     public final void set(long newValue) {
84         value = newValue;
85     }
86   
87     /**
88      * Set to the give value and return the old value.
89      *
90      * @param newValue the new value
91      * @return the previous value
92      */

93     public final long getAndSet(long newValue) {
94         while (true) {
95             long current = get();
96             if (compareAndSet(current, newValue))
97                 return current;
98         }
99     }
100   
101     /**
102      * Atomically set the value to the given updated value
103      * if the current value <tt>==</tt> the expected value.
104      * @param expect the expected value
105      * @param update the new value
106      * @return true if successful. False return indicates that
107      * the actual value was not equal to the expected value.
108      */

109     public final boolean compareAndSet(long expect, long update) {
110       return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
111     }
112
113     /**
114      * Atomically set the value to the given updated value
115      * if the current value <tt>==</tt> the expected value.
116      * May fail spuriously.
117      * @param expect the expected value
118      * @param update the new value
119      * @return true if successful.
120      */

121     public final boolean weakCompareAndSet(long expect, long update) {
122       return unsafe.compareAndSwapLong(this, valueOffset, expect, update);
123     }
124   
125     /**
126      * Atomically increment by one the current value.
127      * @return the previous value
128      */

129     public final long getAndIncrement() {
130         while (true) {
131             long current = get();
132             long next = current + 1;
133             if (compareAndSet(current, next))
134                 return current;
135         }
136     }
137   
138   
139     /**
140      * Atomically decrement by one the current value.
141      * @return the previous value
142      */

143     public final long getAndDecrement() {
144         while (true) {
145             long current = get();
146             long next = current - 1;
147             if (compareAndSet(current, next))
148                 return current;
149         }
150     }
151   
152   
153     /**
154      * Atomically add the given value to current value.
155      * @param delta the value to add
156      * @return the previous value
157      */

158     public final long getAndAdd(long delta) {
159         while (true) {
160             long current = get();
161             long next = current + delta;
162             if (compareAndSet(current, next))
163                 return current;
164         }
165     }
166   
167     /**
168      * Atomically increment by one the current value.
169      * @return the updated value
170      */

171     public final long incrementAndGet() {
172         for (;;) {
173             long current = get();
174             long next = current + 1;
175             if (compareAndSet(current, next))
176                 return next;
177         }
178     }
179     
180     /**
181      * Atomically decrement by one the current value.
182      * @return the updated value
183      */

184     public final long decrementAndGet() {
185         for (;;) {
186             long current = get();
187             long next = current - 1;
188             if (compareAndSet(current, next))
189                 return next;
190         }
191     }
192   
193   
194     /**
195      * Atomically add the given value to current value.
196      * @param delta the value to add
197      * @return the updated value
198      */

199     public final long addAndGet(long delta) {
200         for (;;) {
201             long current = get();
202             long next = current + delta;
203             if (compareAndSet(current, next))
204                 return next;
205         }
206     }
207   
208     /**
209      * Returns the String representation of the current value.
210      * @return the String representation of the current value.
211      */

212     public String JavaDoc toString() {
213         return Long.toString(get());
214     }
215
216
217     public int intValue() {
218     return (int)get();
219     }
220
221     public long longValue() {
222     return (long)get();
223     }
224
225     public float floatValue() {
226     return (float)get();
227     }
228
229     public double doubleValue() {
230     return (double)get();
231     }
232   
233 }
234
Popular Tags