I want to know if the JMM will permit an implementation to reorder the access to the ai
and ada
variables to behave differently than the intention shown in the code.
The intention is that the method perform ops is the next:
What happens after the index reached 1000 is non-important to me. I actually want to use the array as a ring, but if this question gets answered I will be able to figure out how to do it.
Basically I want to avoid locks and rely on atomic and lock-free objects. I don't know however if in this specific case I still need implicit synchronization.
AtomicInteger ai = new AtomicInteger(0);
// let's say all values are null by default
AtomicDoubleArray ada = new AtomicDoubleArray(1000);
int rn = 4; // dice rolled...
void perfomOps(AtomicInteger ai, AtomicDoubleArray ada) {
int i = ai.getAndIncrement();
ada.set(i, rn);
spinlock(ada, i);
printSum(ada, i);
}
void spinlock(AtomicDoubleArray ada, int idx) {
// spinlock in case the other threads couln't write to older indexes yet
if (idx > 0)
for (int c = 0;c < idx; c++)
while (i = ada.get(c) == null);
}
void printSum(AtomicDoubleArray ada, int idx) {
double sum = 0;
for (int i = 0;i < idx; i++)
sum = sum + ada.get(i);
Sytem.out.println(sum);
}
// thread 1
perfomOps(ai, ada); // lets say we get 4 printed
// thread 2
perfomOps(ai, ada); // lets say we get 8 printed
// thread 3
perfomOps(ai, ada); // lets say we get 12 printed
Other threads will keep doing the same, it can happen that the print order is not as expected, like 8, 12 and then 4. But assuming a next thread comes in, then it will see correct values and correctly print now 16.
All this fancy stuff is to avoid making explicit locks in order to measure which one performs better, the lockfree version or the synchronized one
The most important rule of the Java Memory Model is (§17.4.5):
A program is correctly synchronized if and only if all sequentially consistent executions are free of data races. If a program is correctly synchronized, then all executions of the program will appear to be sequentially consistent (§17.4.3).
If all shared variables are volatile or atomic, then there are no data races. That means sequential consistency is guaranteed. And that means, there will be no reorderings visible in the behaviour of the program.