Например, если я буду запускать этот код из нескольких потоков и каждого потока много раз, будет ли потенциальная гонка данных?
public boolean swap(int i, int j) {
if (value.get(i) <= 0 || value.get(j) >= maxval) {
return false;
}
value.decrementAndGet(i);
value.incrementAndGet(j);
return true;
}
Кстати, есть ли разница, если я использую декремент AndGet или getAndDecrement здесь? Значение
здесь - AtomicIntegerArray. Мне нужно выполнить тест производительности между различными методами синхронизации. Таким образом, я поменяю элементы в ценности и посмотрю, равна ли сумма вывода ожидаемой
. Моя задача - найти метод, который «не должен быть DRF», но «все равно должен быть без взаимоблокировки», и также намного быстрее, чем ReentrantLock. Поэтому я беспокоюсь о поиске метода, который имеет гонку данных ...
Как написано выше, все методы AtomicInteger являются потокобезопасными.
будет потенциально гонка данныхТехнически да, будет гонка данных, потому что
Вы дважды вызываете get при оценке логического выражения; Выражение «AtomicInteger является потокобезопасным» означает, что каждый поток, вызывающий, например, value.decrementAndGet(i) (и все другие методы на основе CAS), в конечном итоге завершит эту операцию успешно. Никаких других гарантий.Использование потокобезопасного класса недостаточно для предотвращения гонок данных. Также я хотел бы упомянуть, что гонка данных не всегда плохая вещь, иногда она приемлема на самом деле.
Различие между decrementAndGet() и getAndDecrement() - это какое значение оно возвращает.