В своем превосходном трактате о многопоточности в C #Джозеф Альбахари предложил следующую простую программу, чтобы продемонстрировать, почему нам нужно использовать некоторую форму ограждения памяти вокруг данные, которые читаются и записываются несколькими потоками. Программа никогда не завершится, если вы скомпилируете ее в режиме Release и бесплатно -запустите без отладчика:
static void Main()
{
bool complete = false;
var t = new Thread(() =>
{
bool toggle = false;
while (!complete) toggle = !toggle;
});
t.Start();
Thread.Sleep(1000);
complete = true;
t.Join(); // Blocks indefinitely
}
Мой вопрос: почему следующая слегка измененная версия вышеуказанной программы больше не блокируется на неопределенный срок??
class Foo
{
public bool Complete { get; set; }
}
class Program
{
static void Main()
{
var foo = new Foo();
var t = new Thread(() =>
{
bool toggle = false;
while (!foo.Complete) toggle = !toggle;
});
t.Start();
Thread.Sleep(1000);
foo.Complete = true;
t.Join(); // No longer blocks indefinitely!!!
}
}
В то время как следующее по-прежнему блокируется на неопределенный срок:
class Foo
{
public bool Complete;// { get; set; }
}
class Program
{
static void Main()
{
var foo = new Foo();
var t = new Thread(() =>
{
bool toggle = false;
while (!foo.Complete) toggle = !toggle;
});
t.Start();
Thread.Sleep(1000);
foo.Complete = true;
t.Join(); // Still blocks indefinitely!!!
}
}
Как и следующее:
class Program
{
static bool Complete { get; set; }
static void Main()
{
var t = new Thread(() =>
{
bool toggle = false;
while (!Complete) toggle = !toggle;
});
t.Start();
Thread.Sleep(1000);
Complete = true;
t.Join(); // Still blocks indefinitely!!!
}
}