The AtomicIntegerArray, AtomicLongArray, and AtomicReferenceArray classes further extend atomic operation support to arrays of int, long and reference types respectively. These classes have index based methods (e.g. get(int i), set(int i, newValue) etc) supporting atomic operations on an array element at that specific index position.
Example
In following example we will see how to use AtomicLongArray. We are going to assign arrays elements with sums of X^n where each element of the array will have different base X i.e. 2, 3,...6, each with exponents 1,2,3,4.... 10. The sum will be accumulated by different thread:
package com.logicbig.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLongArray;
import java.util.stream.IntStream;
public class AtomicLongArrayExample {
private static int len = 5;
private static AtomicLongArray sumArray = new AtomicLongArray(len);
public static void main(String[] args) throws InterruptedException {
for (int k = 0; k < 3; k++) {
IntStream.range(0, len).forEach(i -> sumArray.set(i, 0L));
ExecutorService es = Executors.newFixedThreadPool(50);
for (int b = 2; b < len + 2; b++) {
for (int i = 1; i <= 10; i++) {
int exponent = i;
int base = b;
es.execute(() -> sumArray.accumulateAndGet(base - 2,
(long) Math.pow(base, exponent),
(d1, d2) -> d1 + d2));
}
}
es.shutdown();
es.awaitTermination(10, TimeUnit.MINUTES);
IntStream.range(0, len)
.forEach(i -> System.out.println(sumArray.get(i)));
System.out.println("-----------");
}
}
}
2046 88572 1398100 12207030 72559410 ----------- 2046 88572 1398100 12207030 72559410 ----------- 2046 88572 1398100 12207030 72559410 -----------
We repeated the whole process 3 times and found that sums were always same.
Without Atomic Access
Let's see how the code will look like without AtomicLongArray and what will be the output.
package com.logicbig.example;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;
public class NoAtomicLongArrayExample {
private static int len = 5;
private static Long[] sumArray = new Long[len];
public static void main(String[] args) throws InterruptedException {
for (int k = 0; k < 3; k++) {
IntStream.range(0, len).forEach(i -> sumArray[i] = 0L);
ExecutorService es = Executors.newFixedThreadPool(50);
for (int b = 2; b < len + 2; b++) {
for (int i = 1; i <= 10; i++) {
int exponent = i;
int base = b;
es.execute(() -> {
sumArray[base - 2] += (long) Math.pow(base, exponent);
});
}
}
es.shutdown();
es.awaitTermination(10, TimeUnit.MINUTES);
IntStream.range(0, len).forEach(i -> System.out.println(sumArray[i]));
System.out.println("-----------");
}
}
}
764 88572 1398100 12207030 72559410 ----------- 2046 88572 1398100 12125780 72559410 ----------- 2046 88572 1398100 12207030 72559410 -----------
The sums are not always same, that's because the compound assignment operation '+=' is not atomic.
Example ProjectDependencies and Technologies Used:
|