I am trying to implement logic that will allow me to update an array in one thread using sun's unsafe.compareAndSwapObject utility while safely iterating over that same array, in a different thread. I believe that the CopyOnWriteArrayList does what I am searching for however it uses locking for the updating and I am trying to develop a solution that does not have any locks.
The compare and swap logic is as follows:
public void add(final Object toAdd) {
Object[] currentObjects;
Object[] newObjects;
do {
currentObjects = this.objects;
newObjects = ArrayUtil.add(currentObjects, toAdd);
} while (!UNSAFE.compareAndSwapObject(this, OBJECTS_OFFSET, currentObjects, newObjects));
}
While the iteration logic is as follows (the toString() is a placeholder):
public void doWork() {
Object[] currentObjects = this.objects;
for (final Object object : currentObjects) {
object.toString();
}
}
My questions are:
- Is this code safe?
- Does this give me the same snapshot behaviour that CopyOnWriteArrayList does?
- If it does, when is the iteration snapshot formed?
- Does the fact that I'm creating a local variable have anything to do this?
- If it does, how does the JVM know to not optimise this away?
- Have I essentially created a variable on the stack that has a reference to the most up to date array object?
Lastly to follow up the third point above about "snapshot" creation, would the following code work the same way:
public void doWork() {
actuallyDoWork(this.objects);
}
public void actuallyDoWork() {
for (final Object object : currentObjects) {
object.toString();
}
}