Я пытаюсь реализовать логику, которая позволит мне обновлять массив в одном потоке с помощью утилиты unsafe.compareAndSwapObject от Sun, одновременно безопасно перебирая этот же массив в другом потоке. Я полагаю, что CopyOnWriteArrayList делает то, что я ищу, однако он использует блокировку для обновления, и я пытаюсь разработать решение, которое не имеет каких-либо блокировок.
Логика сравнения и свопинга выглядит следующим образом:
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));
}
Хотя логика итерации следующая (toString () является заполнителем):
public void doWork() {
Object[] currentObjects = this.objects;
for (final Object object : currentObjects) {
object.toString();
}
}
Мои вопросы:
- Безопасен ли этот код?
- Дает ли это мне такое же поведение моментального снимка, как CopyOnWriteArrayList?
- Если да, когда формируется моментальный снимок итерации?
- Имеет ли факт, что я создаю локальную переменную, что-нибудь для этого?
- Если да, как JVM узнает, что это не оптимизировать?
- По сути, я создал переменную в стеке, которая имеет ссылку на самый актуальный объект массива?
И наконец, следуя третьему пункту выше о создании «снимка», следующий код будет работать так же:
public void doWork() {
actuallyDoWork(this.objects);
}
public void actuallyDoWork() {
for (final Object object : currentObjects) {
object.toString();
}
}