Для получения триального ключа
заполните форму ниже
Team License (базовая версия)
Enterprise License (расширенная версия)
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
GBP
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

** На сайте установлена reCAPTCHA и применяются
Политика конфиденциальности и Условия использования Google.
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте папку
Spam/Junk и нажмите на письме кнопку "Не спам".
Так Вы не пропустите ответы от нашей команды.

>
>
>
V6074. Non-atomic modification of volat…
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Диагностика микро-оптимизаций (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Cтандарт MISRA
Стандарт AUTOSAR
Дополнительная информация
Оглавление

V6074. Non-atomic modification of volatile variable.

4 октября 2019 г.

Анализатор обнаружил неатомарное изменение 'volatile' переменной, которое может привести к состоянию гонки.

Известно, что использование модификатора 'volatile' гарантирует, что все потоки будут видеть актуальное значение соответствующей переменной. К этому можно добавить, что модификатор 'volatile' используется для того, чтобы указать JVM, что все операции присвоения этой переменной и все операции чтения из неё должны быть атомарными.

Можно посчитать, что пометки переменных как 'volatile' будет достаточно, чтобы безопасно их использовать в многопоточном приложении! Но что будет, если изменять 'volatile' переменную, будущее значение которой зависит от текущего?

К таким операциям можно отнести:

  • var++, --var, ...
  • var += smt, var *= smt, ...
  • ...

Рассмотрим использование 'volatile' переменной в качестве счетчика (counter++).

class Counter
{
  private volatile int counter = 0;
  ....
  public void increment()
  {
    counter++; // counter = counter + 1
  }
  ....
}

Такая операция выглядит как одна операция, но в действительности это целая последовательность операций чтения-изменения-записи. Здесь и кроется состояние гонки.

Предположим, что 2 потока одновременно работают с объектом класса Counter и выполняют инкремент переменной 'counter' (10):

[counter == 10, temp == 10] Поток N1 считывает значение 'counter'во временную переменную.

[counter == 10, temp == 11] Поток N1 изменяет временную переменную.

[counter == 10, temp == 10] Поток N2 считывает значение 'counter'во временную переменную.

[counter == 11, temp == 11] Поток N1 записывает временную переменную в 'counter'.

[counter == 11, temp == 11] Поток N2 изменяет временную переменную.

[counter == 11, temp == 11] Поток N2 записывает временную переменную в 'counter'.

Ожидалось значение переменной 'counter' равное 12 (а не 11), так как 2 потока выполнили инкремент над одной и той же переменной. Также возможна ситуация, когда потоки выполнят инкремент друг за другом, и в таком случае все будет так, как и ожидалось. Как итог, раз на раз не приходится!

Чтобы избежать подобного поведения неатомарных операций для разделяемых переменных, можно использовать:

  • Блок 'synchronized',
  • Классы из пакета java.util.concurrent.atomic,
  • Функциональность блокировок из пакета java.util.concurrent.locks

Пример корректного кода:

class Counter
{
  private volatile int counter = 0;
  ....
  public synchronized void increment()
  {
    counter++;
  }
  ....
}

или

class Counter
{
  private final AtomicInteger counter = new AtomicInteger(0);
  ....
  public void increment()
  {
    counter.incrementAndGet();
  }
  ....
}

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V6074.

Этот сайт использует куки и другие технологии, чтобы предоставить вам более персонализированный опыт. Продолжая просмотр страниц нашего веб-сайта, вы принимаете условия использования этих файлов. Если вы не хотите, чтобы ваши данные обрабатывались, пожалуйста, покиньте данный сайт. Подробнее →
Принять