Допустим, есть несколько потоков, они прибавляют некоторые значения в volatile-переменную (типа синглтон), и выводят значения этой переменной после суммирования в реальном времени (ну должно быть в реальном времени). Все операции - только с целыми числами.
Можно ли так делать? Какие возникнут проблемы?
Ответ
Так делать нельзя. Операции с volatile-переменной не являются атомарными. Ключевое слово volatile лишь сообщает компилятору о том, что переменная может быть изменена либо извне программы, либо другим потоком и нельзя кэшировать её значение, т.е. значение всегда должно считываться/записываться напрямую в ячейку памяти.
В качестве примера рассмотрим выполнение кода
i = i + 1;
Пусть i == 0 и у нас есть два потока, одновременно выполняющих этот код. Тогда возможна следующая ситуация (regX - регистр процессора):
Поток 1 Поток 2 Результат
mov regA, [i] | | regA == 0
| mov regB, [i] | regB == 0
| add regB, 1 | regB == 1
| mov [i], regB | i == 1
add regA, 1 | | regA == 1
mov [i], regA | | i == 1
То есть, код выполнился два раза, но переменная i тем не менее увеличилась только на единицу.
Если Вам нужен потокобезопасный счётчик, используйте AtomicInteger
Комментариев нет:
Отправить комментарий