Безопасен ли доступ через 'Instance' к классу 'Toggle ()'? Если да, то по каким предположениям, правилам и т. Д. Если нет, почему и как я могу это исправить?
Нет, это не потокобезопасно.
По сути, оба потока могут запускать функцию Toggle
одновременно, поэтому это может произойти
// thread 1 is running this code
if(value == 0)
{
value = 1;
// RIGHT NOW, thread 2 steps in.
// It sees value as 1, so runs the other branch, and changes it to 0
// This causes your method to return 0 even though you actually want 1
}
else if(value == 1)
{
value = 0;
}
return value;
Вам необходимо оперировать следующим предположением.
Если запущены 2 потока, они могут и будут чередоваться и взаимодействовать друг с другом случайным образом в любой точке. Вы можете пройти половину пути, записывая или читая 64-разрядное целое число или число с плавающей запятой (на 32-разрядном процессоре), и другой поток может подключиться и изменить его из-под себя.
Если 2 потока никогда не имеют доступа к чему-либо общему, это не имеет значения, но как только они это сделают, вам нужно не допустить, чтобы они наступали друг другу на пальцы ног. В .NET это можно сделать с помощью блокировок.
Вы можете решить, что и где заблокировать, подумав о таких вещах:
Для данного блока кода, если значение something
изменится из-под меня, будет ли это иметь значение? Если это так, вам нужно заблокировать этот something
на время кода, где это будет иметь значение.
Глядя на ваш пример еще раз
// we read value here
if(value == 0)
{
value = 1;
}
else if(value == 1)
{
value = 0;
}
// and we return it here
return value;
Для того чтобы это вернуло то, что мы ожидаем, мы предполагаем, что value
не будет изменено между чтением и return
. Чтобы это предположение было верным, вам нужно заблокировать value
на время этого кодового блока.
Итак, вы бы сделали это:
lock( value )
{
if(value == 0)
... // all your code here
return value;
}
ОДНАКО
В .NET вы можете заблокировать только ссылочные типы. Int32 - это тип значения, поэтому мы не можем его заблокировать.
Мы решаем эту проблему, вводя фиктивный объект и блокируя , который , везде, где мы хотим заблокировать 'значение'.
Это то, что Бен Шейрман имеет в виду.