Почему эта Java-программа, содержащая две изменчивые записи данных, свободна? - PullRequest
0 голосов
/ 18 марта 2019

Рассмотрим следующую Java-программу:

static volatile int shared;

public static void main(final String[] args) {
  final Runnable r = () -> {
    shared = 1;
  };

  new Thread(r).start();
  new Thread(r).start();
}

Поскольку shared помечено volatile, я хочу сказать, что эта программа свободна от гонок данных. Однако как это должно быть мотивировано на основе JLS (скажем, версия 11)?

В главе 17 нам говорят:

Когда программа содержит два конфликтующих доступа (§17.4.1), которые не упорядочены отношением «происходит до», говорят, что она содержит гонку данных.

Я принимаю это за определение гонок данных, предоставляемых JLS. Тогда у нас есть раздел 17.4.1, говорящий нам:

Два доступа к одной и той же переменной (чтение или запись в нее) называются конфликтующими, если хотя бы один из них является записью.

Хорошо, у нас здесь конфликты доступа, поскольку у нас есть две записи в shared. Теперь между этими двумя записями должны быть отношения «до того, как это произойдет», иначе у нас гонка. Однако мне так и не удалось выяснить, почему мы имеем такое отношение. Глава 17 говорит мне, что:

Если действие x синхронизируется со следующим действием y, то у нас также есть hb (x, y).

И та же глава говорит мне:

Запись в энергозависимую переменную v (§8.3.1.4) синхронизирует все последующие чтения v любым потоком (где «последующий» определяется в соответствии с порядком синхронизации).

Но мне не удалось обнаружить, что что-то случилось, прежде чем связать записи с переменными. Почему это так?

1 Ответ

1 голос
/ 20 марта 2019

Доступ к переменной volatile равен , никогда становится объектом гонки данных .

Это не так очевидно из JLS, но во фразе

(§17.4.1) Два доступа к одной и той же переменной (чтение или запись в нее) называются конфликтующими, если хотя бы один из них является записью.

термины «чтение» и «запись» не являются общими, но описаны в следующем разделе «17.4.2 Действия» как доступ к энергонезависимой переменной:

Чтение (нормальное или энергонезависимое). Чтение переменной.

Запись (нормальное или энергонезависимое). Запись переменной.

В этом разделе доступ к переменной volatile классифицируется как часть Действия синхронизации , с различными терминами "Volatile read" и "Volatile write":

- Volatile read . Изменчивое чтение переменной.

- Летучая запись . Нестабильная запись переменной.

Поскольку только (энергонезависимые) чтения и записи могут конфликтовать, только эти обращения могут содержать гонку данных . Volatile чтение и запись никогда не могут конфликтовать и могут никогда содержать гонку данных .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...