KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*
2  * @(#)AtomicIntegerArray.java 1.6 04/01/24
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 import java.util.*;
11
12 /**
13  * An <tt>int</tt> array in which elements may be updated atomically.
14  * See the {@link java.util.concurrent.atomic} package
15  * specification for description of the properties of atomic
16  * variables.
17  * @since 1.5
18  * @author Doug Lea
19  */

20 public class AtomicIntegerArray implements java.io.Serializable JavaDoc {
21     private static final long serialVersionUID = 2862133569453604235L;
22
23    // setup to use Unsafe.compareAndSwapInt for updates
24
private static final Unsafe unsafe = Unsafe.getUnsafe();
25     private static final int base = unsafe.arrayBaseOffset(int[].class);
26     private static final int scale = unsafe.arrayIndexScale(int[].class);
27     private final int[] array;
28
29     private long rawIndex(int i) {
30         if (i < 0 || i >= array.length)
31             throw new IndexOutOfBoundsException JavaDoc("index " + i);
32         return base + i * scale;
33     }
34
35     /**
36      * Create a new AtomicIntegerArray of given length.
37      *
38      * @param length the length of the array
39      */

40     public AtomicIntegerArray(int length) {
41         array = new int[length];
42         // must perform at least one volatile write to conform to JMM
43
if (length > 0)
44             unsafe.putIntVolatile(array, rawIndex(0), 0);
45     }
46
47     /**
48      * Create a new AtomicIntegerArray with the same length as, and
49      * all elements copied from, the given array.
50      *
51      * @param array the array to copy elements from
52      * @throws NullPointerException if array is null
53      */

54     public AtomicIntegerArray(int[] array) {
55         if (array == null)
56             throw new NullPointerException JavaDoc();
57         int length = array.length;
58         this.array = new int[length];
59         if (length > 0) {
60             int last = length-1;
61             for (int i = 0; i < last; ++i)
62                 this.array[i] = array[i];
63             // Do the last write as volatile
64
unsafe.putIntVolatile(this.array, rawIndex(last), array[last]);
65         }
66     }
67
68     /**
69      * Returns the length of the array.
70      *
71      * @return the length of the array
72      */

73     public final int length() {
74         return array.length;
75     }
76
77     /**
78      * Get the current value at position <tt>i</tt>.
79      *
80      * @param i the index
81      * @return the current value
82      */

83     public final int get(int i) {
84         return unsafe.getIntVolatile(array, rawIndex(i));
85     }
86  
87     /**
88      * Set the element at position <tt>i</tt> to the given value.
89      *
90      * @param i the index
91      * @param newValue the new value
92      */

93     public final void set(int i, int newValue) {
94         unsafe.putIntVolatile(array, rawIndex(i), newValue);
95     }
96   
97     /**
98      * Set the element at position <tt>i</tt> to the given value and return the
99      * old value.
100      *
101      * @param i the index
102      * @param newValue the new value
103      * @return the previous value
104      */

105     public final int getAndSet(int i, int newValue) {
106         while (true) {
107             int current = get(i);
108             if (compareAndSet(i, current, newValue))
109                 return current;
110         }
111     }
112   
113     /**
114      * Atomically set the value to the given updated value
115      * if the current value <tt>==</tt> the expected value.
116      *
117      * @param i the index
118      * @param expect the expected value
119      * @param update the new value
120      * @return true if successful. False return indicates that
121      * the actual value was not equal to the expected value.
122      */

123     public final boolean compareAndSet(int i, int expect, int update) {
124         return unsafe.compareAndSwapInt(array, rawIndex(i),
125                                         expect, update);
126     }
127
128     /**
129      * Atomically set the value to the given updated value
130      * if the current value <tt>==</tt> the expected value.
131      * May fail spuriously.
132      *
133      * @param i the index
134      * @param expect the expected value
135      * @param update the new value
136      * @return true if successful.
137      */

138     public final boolean weakCompareAndSet(int i, int expect, int update) {
139         return compareAndSet(i, expect, update);
140     }
141
142     /**
143      * Atomically increment by one the element at index <tt>i</tt>.
144      *
145      * @param i the index
146      * @return the previous value;
147      */

148     public final int getAndIncrement(int i) {
149         while (true) {
150             int current = get(i);
151             int next = current + 1;
152             if (compareAndSet(i, current, next))
153                 return current;
154         }
155     }
156   
157     /**
158      * Atomically decrement by one the element at index <tt>i</tt>.
159      *
160      * @param i the index
161      * @return the previous value;
162      */

163     public final int getAndDecrement(int i) {
164         while (true) {
165             int current = get(i);
166             int next = current - 1;
167             if (compareAndSet(i, current, next))
168                 return current;
169         }
170     }
171   
172     /**
173      * Atomically add the given value to element at index <tt>i</tt>.
174      *
175      * @param i the index
176      * @param delta the value to add
177      * @return the previous value;
178      */

179     public final int getAndAdd(int i, int delta) {
180         while (true) {
181             int current = get(i);
182             int next = current + delta;
183             if (compareAndSet(i, current, next))
184                 return current;
185         }
186     }
187
188     /**
189      * Atomically increment by one the element at index <tt>i</tt>.
190      *
191      * @param i the index
192      * @return the updated value;
193      */

194     public final int incrementAndGet(int i) {
195         while (true) {
196             int current = get(i);
197             int next = current + 1;
198             if (compareAndSet(i, current, next))
199                 return next;
200         }
201     }
202   
203     /**
204      * Atomically decrement by one the element at index <tt>i</tt>.
205      *
206      * @param i the index
207      * @return the updated value;
208      */

209     public final int decrementAndGet(int i) {
210         while (true) {
211             int current = get(i);
212             int next = current - 1;
213             if (compareAndSet(i, current, next))
214                 return next;
215         }
216     }
217   
218     /**
219      * Atomically add the given value to element at index <tt>i</tt>.
220      *
221      * @param i the index
222      * @param delta the value to add
223      * @return the updated value;
224      */

225     public final int addAndGet(int i, int delta) {
226         while (true) {
227             int current = get(i);
228             int next = current + delta;
229             if (compareAndSet(i, current, next))
230                 return next;
231         }
232     }
233  
234     /**
235      * Returns the String representation of the current values of array.
236      * @return the String representation of the current values of array.
237      */

238     public String JavaDoc toString() {
239         if (array.length > 0) // force volatile read
240
get(0);
241         return Arrays.toString(array);
242     }
243
244 }
245
Popular Tags