1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.  Oracle designates this
7  * particular file as subject to the "Classpath" exception as provided
8  * by Oracle in the LICENSE file that accompanied this code.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */

24
25 /*
26  * This file is available under and governed by the GNU General Public
27  * License version 2 only, as published by the Free Software Foundation.
28  * However, the following notice accompanied the original version of this
29  * file:
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
38 import java.lang.invoke.MethodHandles;
39 import java.lang.invoke.VarHandle;
40 import java.util.function.IntBinaryOperator;
41 import java.util.function.IntUnaryOperator;
42
43 /**
44  * An {@code int} array in which elements may be updated atomically.
45  * See the {@link VarHandle} specification for descriptions of the
46  * properties of atomic accesses.
47  * @since 1.5
48  * @author Doug Lea
49  */

50 public class AtomicIntegerArray implements java.io.Serializable {
51     private static final long serialVersionUID = 2862133569453604235L;
52     private static final VarHandle AA
53         = MethodHandles.arrayElementVarHandle(int[].class);
54     private final int[] array;
55
56     /**
57      * Creates a new AtomicIntegerArray of the given length, with all
58      * elements initially zero.
59      *
60      * @param length the length of the array
61      */

62     public AtomicIntegerArray(int length) {
63         array = new int[length];
64     }
65
66     /**
67      * Creates a new AtomicIntegerArray with the same length as, and
68      * all elements copied from, the given array.
69      *
70      * @param array the array to copy elements from
71      * @throws NullPointerException if array is null
72      */

73     public AtomicIntegerArray(int[] array) {
74         // Visibility guaranteed by final field guarantees
75         this.array = array.clone();
76     }
77
78     /**
79      * Returns the length of the array.
80      *
81      * @return the length of the array
82      */

83     public final int length() {
84         return array.length;
85     }
86
87     /**
88      * Returns the current value of the element at index {@code i},
89      * with memory effects as specified by {@link VarHandle#getVolatile}.
90      *
91      * @param i the index
92      * @return the current value
93      */

94     public final int get(int i) {
95         return (int)AA.getVolatile(array, i);
96     }
97
98     /**
99      * Sets the element at index {@code i} to {@code newValue},
100      * with memory effects as specified by {@link VarHandle#setVolatile}.
101      *
102      * @param i the index
103      * @param newValue the new value
104      */

105     public final void set(int i, int newValue) {
106         AA.setVolatile(array, i, newValue);
107     }
108
109     /**
110      * Sets the element at index {@code i} to {@code newValue},
111      * with memory effects as specified by {@link VarHandle#setRelease}.
112      *
113      * @param i the index
114      * @param newValue the new value
115      * @since 1.6
116      */

117     public final void lazySet(int i, int newValue) {
118         AA.setRelease(array, i, newValue);
119     }
120
121     /**
122      * Atomically sets the element at index {@code i} to {@code
123      * newValue} and returns the old value,
124      * with memory effects as specified by {@link VarHandle#getAndSet}.
125      *
126      * @param i the index
127      * @param newValue the new value
128      * @return the previous value
129      */

130     public final int getAndSet(int i, int newValue) {
131         return (int)AA.getAndSet(array, i, newValue);
132     }
133
134     /**
135      * Atomically sets the element at index {@code i} to {@code
136      * newValue} if the element's current value {@code == expectedValue},
137      * with memory effects as specified by {@link VarHandle#compareAndSet}.
138      *
139      * @param i the index
140      * @param expectedValue the expected value
141      * @param newValue the new value
142      * @return {@code trueif successful. False return indicates that
143      * the actual value was not equal to the expected value.
144      */

145     public final boolean compareAndSet(int i, int expectedValue, int newValue) {
146         return AA.compareAndSet(array, i, expectedValue, newValue);
147     }
148
149     /**
150      * Possibly atomically sets the element at index {@code i} to
151      * {@code newValue} if the element's current value {@code == expectedValue},
152      * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
153      *
154      * @deprecated This method has plain memory effects but the method
155      * name implies volatile memory effects (see methods such as
156      * {@link #compareAndExchange} and {@link #compareAndSet}).  To avoid
157      * confusion over plain or volatile memory effects it is recommended that
158      * the method {@link #weakCompareAndSetPlain} be used instead.
159      *
160      * @param i the index
161      * @param expectedValue the expected value
162      * @param newValue the new value
163      * @return {@code trueif successful
164      * @see #weakCompareAndSetPlain
165      */

166     @Deprecated(since="9")
167     public final boolean weakCompareAndSet(int i, int expectedValue, int newValue) {
168         return AA.weakCompareAndSetPlain(array, i, expectedValue, newValue);
169     }
170
171     /**
172      * Possibly atomically sets the element at index {@code i} to
173      * {@code newValue} if the element's current value {@code == expectedValue},
174      * with memory effects as specified by {@link VarHandle#weakCompareAndSetPlain}.
175      *
176      * @param i the index
177      * @param expectedValue the expected value
178      * @param newValue the new value
179      * @return {@code trueif successful
180      * @since 9
181      */

182     public final boolean weakCompareAndSetPlain(int i, int expectedValue, int newValue) {
183         return AA.weakCompareAndSetPlain(array, i, expectedValue, newValue);
184     }
185
186     /**
187      * Atomically increments the value of the element at index {@code i},
188      * with memory effects as specified by {@link VarHandle#getAndAdd}.
189      *
190      * <p>Equivalent to {@code getAndAdd(i, 1)}.
191      *
192      * @param i the index
193      * @return the previous value
194      */

195     public final int getAndIncrement(int i) {
196         return (int)AA.getAndAdd(array, i, 1);
197     }
198
199     /**
200      * Atomically decrements the value of the element at index {@code i},
201      * with memory effects as specified by {@link VarHandle#getAndAdd}.
202      *
203      * <p>Equivalent to {@code getAndAdd(i, -1)}.
204      *
205      * @param i the index
206      * @return the previous value
207      */

208     public final int getAndDecrement(int i) {
209         return (int)AA.getAndAdd(array, i, -1);
210     }
211
212     /**
213      * Atomically adds the given value to the element at index {@code i},
214      * with memory effects as specified by {@link VarHandle#getAndAdd}.
215      *
216      * @param i the index
217      * @param delta the value to add
218      * @return the previous value
219      */

220     public final int getAndAdd(int i, int delta) {
221         return (int)AA.getAndAdd(array, i, delta);
222     }
223
224     /**
225      * Atomically increments the value of the element at index {@code i},
226      * with memory effects as specified by {@link VarHandle#getAndAdd}.
227      *
228      * <p>Equivalent to {@code addAndGet(i, 1)}.
229      *
230      * @param i the index
231      * @return the updated value
232      */

233     public final int incrementAndGet(int i) {
234         return (int)AA.getAndAdd(array, i, 1) + 1;
235     }
236
237     /**
238      * Atomically decrements the value of the element at index {@code i},
239      * with memory effects as specified by {@link VarHandle#getAndAdd}.
240      *
241      * <p>Equivalent to {@code addAndGet(i, -1)}.
242      *
243      * @param i the index
244      * @return the updated value
245      */

246     public final int decrementAndGet(int i) {
247         return (int)AA.getAndAdd(array, i, -1) - 1;
248     }
249
250     /**
251      * Atomically adds the given value to the element at index {@code i},
252      * with memory effects as specified by {@link VarHandle#getAndAdd}.
253      *
254      * @param i the index
255      * @param delta the value to add
256      * @return the updated value
257      */

258     public final int addAndGet(int i, int delta) {
259         return (int)AA.getAndAdd(array, i, delta) + delta;
260     }
261
262     /**
263      * Atomically updates (with memory effects as specified by {@link
264      * VarHandle#compareAndSet}) the element at index {@code i} with
265      * the results of applying the given function, returning the
266      * previous value. The function should be side-effect-free, since
267      * it may be re-applied when attempted updates fail due to
268      * contention among threads.
269      *
270      * @param i the index
271      * @param updateFunction a side-effect-free function
272      * @return the previous value
273      * @since 1.8
274      */

275     public final int getAndUpdate(int i, IntUnaryOperator updateFunction) {
276         int prev = get(i), next = 0;
277         for (boolean haveNext = false;;) {
278             if (!haveNext)
279                 next = updateFunction.applyAsInt(prev);
280             if (weakCompareAndSetVolatile(i, prev, next))
281                 return prev;
282             haveNext = (prev == (prev = get(i)));
283         }
284     }
285
286     /**
287      * Atomically updates (with memory effects as specified by {@link
288      * VarHandle#compareAndSet}) the element at index {@code i} with
289      * the results of applying the given function, returning the
290      * updated value. The function should be side-effect-free, since it
291      * may be re-applied when attempted updates fail due to contention
292      * among threads.
293      *
294      * @param i the index
295      * @param updateFunction a side-effect-free function
296      * @return the updated value
297      * @since 1.8
298      */

299     public final int updateAndGet(int i, IntUnaryOperator updateFunction) {
300         int prev = get(i), next = 0;
301         for (boolean haveNext = false;;) {
302             if (!haveNext)
303                 next = updateFunction.applyAsInt(prev);
304             if (weakCompareAndSetVolatile(i, prev, next))
305                 return next;
306             haveNext = (prev == (prev = get(i)));
307         }
308     }
309
310     /**
311      * Atomically updates (with memory effects as specified by {@link
312      * VarHandle#compareAndSet}) the element at index {@code i} with
313      * the results of applying the given function to the current and
314      * given values, returning the previous value. The function should
315      * be side-effect-free, since it may be re-applied when attempted
316      * updates fail due to contention among threads.  The function is
317      * applied with the current value of the element at index {@code i}
318      * as its first argument, and the given update as the second
319      * argument.
320      *
321      * @param i the index
322      * @param x the update value
323      * @param accumulatorFunction a side-effect-free function of two arguments
324      * @return the previous value
325      * @since 1.8
326      */

327     public final int getAndAccumulate(int i, int x,
328                                       IntBinaryOperator accumulatorFunction) {
329         int prev = get(i), next = 0;
330         for (boolean haveNext = false;;) {
331             if (!haveNext)
332                 next = accumulatorFunction.applyAsInt(prev, x);
333             if (weakCompareAndSetVolatile(i, prev, next))
334                 return prev;
335             haveNext = (prev == (prev = get(i)));
336         }
337     }
338
339     /**
340      * Atomically updates (with memory effects as specified by {@link
341      * VarHandle#compareAndSet}) the element at index {@code i} with
342      * the results of applying the given function to the current and
343      * given values, returning the updated value. The function should
344      * be side-effect-free, since it may be re-applied when attempted
345      * updates fail due to contention among threads.  The function is
346      * applied with the current value of the element at index {@code i}
347      * as its first argument, and the given update as the second
348      * argument.
349      *
350      * @param i the index
351      * @param x the update value
352      * @param accumulatorFunction a side-effect-free function of two arguments
353      * @return the updated value
354      * @since 1.8
355      */

356     public final int accumulateAndGet(int i, int x,
357                                       IntBinaryOperator accumulatorFunction) {
358         int prev = get(i), next = 0;
359         for (boolean haveNext = false;;) {
360             if (!haveNext)
361                 next = accumulatorFunction.applyAsInt(prev, x);
362             if (weakCompareAndSetVolatile(i, prev, next))
363                 return next;
364             haveNext = (prev == (prev = get(i)));
365         }
366     }
367
368     /**
369      * Returns the String representation of the current values of array.
370      * @return the String representation of the current values of array
371      */

372     public String toString() {
373         int iMax = array.length - 1;
374         if (iMax == -1)
375             return "[]";
376
377         StringBuilder b = new StringBuilder();
378         b.append('[');
379         for (int i = 0; ; i++) {
380             b.append(get(i));
381             if (i == iMax)
382                 return b.append(']').toString();
383             b.append(',').append(' ');
384         }
385     }
386
387     // jdk9
388
389     /**
390      * Returns the current value of the element at index {@code i},
391      * with memory semantics of reading as if the variable was declared
392      * non-{@code volatile}.
393      *
394      * @param i the index
395      * @return the value
396      * @since 9
397      */

398     public final int getPlain(int i) {
399         return (int)AA.get(array, i);
400     }
401
402     /**
403      * Sets the element at index {@code i} to {@code newValue},
404      * with memory semantics of setting as if the variable was
405      * declared non-{@code volatile} and non-{@code final}.
406      *
407      * @param i the index
408      * @param newValue the new value
409      * @since 9
410      */

411     public final void setPlain(int i, int newValue) {
412         AA.set(array, i, newValue);
413     }
414
415     /**
416      * Returns the current value of the element at index {@code i},
417      * with memory effects as specified by {@link VarHandle#getOpaque}.
418      *
419      * @param i the index
420      * @return the value
421      * @since 9
422      */

423     public final int getOpaque(int i) {
424         return (int)AA.getOpaque(array, i);
425     }
426
427     /**
428      * Sets the element at index {@code i} to {@code newValue},
429      * with memory effects as specified by {@link VarHandle#setOpaque}.
430      *
431      * @param i the index
432      * @param newValue the new value
433      * @since 9
434      */

435     public final void setOpaque(int i, int newValue) {
436         AA.setOpaque(array, i, newValue);
437     }
438
439     /**
440      * Returns the current value of the element at index {@code i},
441      * with memory effects as specified by {@link VarHandle#getAcquire}.
442      *
443      * @param i the index
444      * @return the value
445      * @since 9
446      */

447     public final int getAcquire(int i) {
448         return (int)AA.getAcquire(array, i);
449     }
450
451     /**
452      * Sets the element at index {@code i} to {@code newValue},
453      * with memory effects as specified by {@link VarHandle#setRelease}.
454      *
455      * @param i the index
456      * @param newValue the new value
457      * @since 9
458      */

459     public final void setRelease(int i, int newValue) {
460         AA.setRelease(array, i, newValue);
461     }
462
463     /**
464      * Atomically sets the element at index {@code i} to {@code newValue}
465      * if the element's current value, referred to as the <em>witness
466      * value</em>, {@code == expectedValue},
467      * with memory effects as specified by
468      * {@link VarHandle#compareAndExchange}.
469      *
470      * @param i the index
471      * @param expectedValue the expected value
472      * @param newValue the new value
473      * @return the witness value, which will be the same as the
474      * expected value if successful
475      * @since 9
476      */

477     public final int compareAndExchange(int i, int expectedValue, int newValue) {
478         return (int)AA.compareAndExchange(array, i, expectedValue, newValue);
479     }
480
481     /**
482      * Atomically sets the element at index {@code i} to {@code newValue}
483      * if the element's current value, referred to as the <em>witness
484      * value</em>, {@code == expectedValue},
485      * with memory effects as specified by
486      * {@link VarHandle#compareAndExchangeAcquire}.
487      *
488      * @param i the index
489      * @param expectedValue the expected value
490      * @param newValue the new value
491      * @return the witness value, which will be the same as the
492      * expected value if successful
493      * @since 9
494      */

495     public final int compareAndExchangeAcquire(int i, int expectedValue, int newValue) {
496         return (int)AA.compareAndExchangeAcquire(array, i, expectedValue, newValue);
497     }
498
499     /**
500      * Atomically sets the element at index {@code i} to {@code newValue}
501      * if the element's current value, referred to as the <em>witness
502      * value</em>, {@code == expectedValue},
503      * with memory effects as specified by
504      * {@link VarHandle#compareAndExchangeRelease}.
505      *
506      * @param i the index
507      * @param expectedValue the expected value
508      * @param newValue the new value
509      * @return the witness value, which will be the same as the
510      * expected value if successful
511      * @since 9
512      */

513     public final int compareAndExchangeRelease(int i, int expectedValue, int newValue) {
514         return (int)AA.compareAndExchangeRelease(array, i, expectedValue, newValue);
515     }
516
517     /**
518      * Possibly atomically sets the element at index {@code i} to
519      * {@code newValue} if the element's current value {@code == expectedValue},
520      * with memory effects as specified by
521      * {@link VarHandle#weakCompareAndSet}.
522      *
523      * @param i the index
524      * @param expectedValue the expected value
525      * @param newValue the new value
526      * @return {@code trueif successful
527      * @since 9
528      */

529     public final boolean weakCompareAndSetVolatile(int i, int expectedValue, int newValue) {
530         return AA.weakCompareAndSet(array, i, expectedValue, newValue);
531     }
532
533     /**
534      * Possibly atomically sets the element at index {@code i} to
535      * {@code newValue} if the element's current value {@code == expectedValue},
536      * with memory effects as specified by
537      * {@link VarHandle#weakCompareAndSetAcquire}.
538      *
539      * @param i the index
540      * @param expectedValue the expected value
541      * @param newValue the new value
542      * @return {@code trueif successful
543      * @since 9
544      */

545     public final boolean weakCompareAndSetAcquire(int i, int expectedValue, int newValue) {
546         return AA.weakCompareAndSetAcquire(array, i, expectedValue, newValue);
547     }
548
549     /**
550      * Possibly atomically sets the element at index {@code i} to
551      * {@code newValue} if the element's current value {@code == expectedValue},
552      * with memory effects as specified by
553      * {@link VarHandle#weakCompareAndSetRelease}.
554      *
555      * @param i the index
556      * @param expectedValue the expected value
557      * @param newValue the new value
558      * @return {@code trueif successful
559      * @since 9
560      */

561     public final boolean weakCompareAndSetRelease(int i, int expectedValue, int newValue) {
562         return AA.weakCompareAndSetRelease(array, i, expectedValue, newValue);
563     }
564
565
566 }
567