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:
|