2013-10-10 6 views
1

Я использую ключевое слово Volatile, но он ведет себя как-то иначе, чем ожидалось.Использование ключевого слова Volatile в C#

Вот мой код

private static volatile int _N = 0; 



var up = Task.Run(() => 
{ 
    for (int i = 0; i < 1000000; i++) 
     _N++; 
}); 
for (int i = 0; i < 1000000; i++) 
    _N--; 
up.Wait(); 
Console.WriteLine(_N); 

_N является переменной класса.

Каждый раз, когда я получаю разные значения, как если бы ключевое слово volatile не использовалось. Правильное ли поведение ключевого слова?

+0

Вы считаете, что ключевое слово volatile используется так же, как, например, 'Volatile.Write'? –

ответ

11

То, что я получаю, является различным числом каждый раз, как если бы ключевое слово volatile не использовалось. Правильное ли поведение ключевого слова?

Указание переменной в качестве летучего не делает либо приращение или операцию декремента атомным. Представьте, что ваш цикл был написан так:

for (int i = 0; i < 1000000; i++) 
{ 
    int x = _N; 
    x++; 
    _N = x; 
} 

Это эффективно, что предыдущий цикл был - это просто, что теперь это ясно, что вы читаете, а затем выполняет операцию, то писать. Нет ничего, чтобы остановить другой поток от записи другого значения между этими двумя операциями.

Для атомизации вы должны использовать Interlocked.Increment и Interlocked.Decrement.

Лично я постараюсь избежать использования volatile, где это возможно. Значение точного смысла этого относительно сложно описать, и трудно рассуждать на мой взгляд. Лучше использовать конструкторы более высокого уровня, где это возможно.

Смежные вопросы