В наиболее сценарии, локальные переменные являются специфическими для потока, поэтому проблемы, связанные с volatile
, совершенно не нужны.
Это изменяется, когда, как и в вашем примере, это «захваченная» переменная - когда она тихо реализована как поле в классе, генерируемом компилятором. Так что теоретически мог бы быть изменчивым, но в большинстве случаев это не стоило бы лишней сложности.
В частности, что-то вроде Monitor
(aka lock
) с Pulse
и т. Д. Может сделать это так же хорошо, как и любое количество других конструкций резьбы.
Threading является сложным, и активный цикл редко лучший способ управлять ...
Re редактирования ... secondThread.Join()
бы очевидное дело - но если вы действительно хотите использовать отдельный токен, см. ниже. Преимущество этого (над такими вещами, как ManualResetEvent
) заключается в том, что он ничего не требует от ОС - он обрабатывается исключительно внутри CLI.
using System;
using System.Threading;
static class Program {
static void WriteLine(string message) {
Console.WriteLine(Thread.CurrentThread.Name + ": " + message);
}
static void Main() {
Thread.CurrentThread.Name = "Main";
object syncLock = new object();
Thread thread = new Thread(DoStuff);
thread.Name = "DoStuff";
lock (syncLock) {
WriteLine("starting second thread");
thread.Start(syncLock);
Monitor.Wait(syncLock);
}
WriteLine("exiting");
}
static void DoStuff(object lockHandle) {
WriteLine("entered");
for (int i = 0; i < 10; i++) {
Thread.Sleep(500);
WriteLine("working...");
}
lock (lockHandle) {
Monitor.Pulse(lockHandle);
}
WriteLine("exiting");
}
}
В данном случае ваша переменная не является локальной! Скорее, это переменная экземпляра в классе, генерируемом компилятором. –
Это семантическая разница - с точки зрения кода, это локальная переменная, которая может быть захвачена ... –
Что я вижу? Это локальная переменная, которая обновляется в другом потоке. И хотя я знаю, что компилятор сделает переменную экземпляра моей локальной переменной, предкомпилятор, по-видимому, не слишком «упрям», чтобы признать это. –