У меня есть вопрос, связанный с моделью памяти C # и потоками. Я не уверен, что следующий код правильный без ключевого слова volatile .
public class A {
private int variableA = 0;
public A() {
variableA = 1;
Thread B = new Thread(new ThreadStart(() => printA())).Start();
}
private void printA() {
System.Console.WriteLine(variableA);
}
}
Меня беспокоит, будет ли гарантировано, что поток B увидит переменную A со значением 1 без использования volatile ? В основном потоке я только назначаю 1 переменной A в конструкторе. После этого я не касаюсь переменной A, она используется только в потоке B, поэтому блокировка, вероятно, не требуется.
Но гарантируется ли, что основной поток очистит свой кэш и запишет содержимое переменной A в основную память, чтобы второй поток мог прочитать вновь присвоенное значение?
Кроме того, гарантируется ли, что второй поток будет считывать содержимое переменной A из основной памяти? Могут ли произойти некоторые оптимизации компилятора, и Поток B может читать содержимое переменной A из кэша вместо основной памяти? Это может произойти при изменении порядка инструкций.
Конечно, добавление volatile к объявлению variableA сделает код правильным. Но это необходимо? Я спрашиваю, потому что я написал некоторый код с инициализацией некоторых энергонезависимых переменных в конструкторе, и переменные позже используются некоторыми потоками Timer, и я не уверен, что это полностью правильно.
А как насчет того же кода в Java?
Спасибо, Михал