I am confused about the safe exchange of arrays between threads in Java, in particular, in memory fences and the keyword synchronized.
This Q & A is useful, but does not answer all my questions: Are Java arrays: synchronized + Atomic * or synchronized?
The following is sample code to demonstrate the problem. Suppose there is a workflow pool that populates SharedTableusing the method add(...). After all workflows are completed, the last thread reads and saves data.
Sample code to demonstrate the problem:
public final class SharedTable {
private final String[] data1Arr;
private final int[] data2Arr;
private final long[] data3Arr;
private final AtomicInteger nextIndex;
public SharedTable(int size) {
this.data1Arr = new String[size];
this.data2Arr = new int[size];
this.data3Arr = new long[size];
this.nextIndex = new AtomicInteger(0);
}
public void addEntry(String data1, int data2, long data3) {
final int index = nextIndex.getAndIncrement();
data1Arr[index] = data1;
data2Arr[index] = data2;
data3Arr[index] = data3;
}
public void save() {
synchronized (this) {
final int usedSide = nextIndex.get();
for (int i = 0; i < usedSide; ++i) {
final String data1 = data1Arr[i];
final int data2 = data2Arr[i];
final long data3 = data3Arr[i];
}
}
}
}
The code example above can also be implemented using Atomic*Array, which acts as an "array of mutable values / references".
public final class SharedTable2 {
private final AtomicReferenceArray<String> data1Arr;
private final AtomicIntegerArray data2Arr;
private final AtomicLongArray data3Arr;
private final AtomicInteger nextIndex;
public SharedTable2(int size) { ... }
public void addEntry(String data1, int data2, long data3) {
final int index = nextIndex.getAndIncrement();
data1Arr.set(index, data1);
...
}
public void save() {
final int usedSide = nextIndex.get();
for (int i = 0; i < usedSide; ++i) {
final String data1 = data1Arr.get(i);
final int data2 = data2Arr.get(i);
final long data3 = data3Arr.get(i);
}
}
}
SharedTable ( -)?SharedTable (?) , , SharedTable2 Atomic*Array.set(...)?
, Java 8 64- x86 (Windows Linux).