Для целей многопоточности ++
и +=
рассматриваются как две операции (четыре для double
и long
). Так что обновления могут забить друг друга. Не просто один, а планировщик, действующий в неподходящий момент, может уничтожить миллисекунды обновлений.
java.util.concurrent.atomic
твой друг.
Ваш код можно сделать безопасным, если вы не возражаете против того, чтобы каждый элемент обновлялся отдельно, и вы не меняете размер (!), Как:
for (int i=0; i < vec.size(); i++) {
synchronized (vec) {
vec.set(i, vec.get(i) + value);
}
}
Если вы хотите добавить изменение размера к Vector
, вам нужно переместить оператор synchronized
за пределы цикла for
, и вы также можете просто использовать обычный новый ArrayList
. На самом деле не очень много пользы для синхронизированного списка.
Но вы можете использовать AtomicIntegerArray
:
private final AtomicIntegerArray ints = new AtomicIntegerArray(KNOWN_SIZE);
[...]
int len = ints.length();
for (int i=0; i<len; ++i) {
ints.addAndGet(i, value);
}
}
Преимущество в том, что нет замков (!) И нет бокса. Реализация тоже довольно забавная, и вам нужно понять, что она выполняет более сложные обновления (например, генераторы случайных чисел).