value++
не является atomic operation
(что означает ни одну неделимую операцию).
За value++
скрыто 3 операции (чтение-изменение-запись) ->
int temp = value;
temp = temp + 1;
value = temp;
При некоторой неудачной синхронизации 2 потока могут прочитать старое значение (int temp = value
) и, таким образом, сгенерировать приращение lost update
-> 2, дающее то же конечное значение.
Это называется race condition
потому что результат операции зависит от планирования и чередования нескольких потоков во время выполнения.
Эта последовательность операций должна быть атомарной c, и для этого необходимо использовать некоторые механизмы синхронизации.
Пример "некоторых" решений:
A. Используйте атоми c переменные (из пакета java.util.concurrent.atomic
). Лучший подход в этом примере
B. Используйте intrinsi c замок (synchronized
)
@ThreadSafe
public class SafeSequence {
private int value;
public synchronized int getNext() {
return value++;
}
}