C # создание общего экземпляра - PullRequest
3 голосов
/ 30 августа 2010

У меня вопрос, почему эта строка - ThreadTest tt = new ThreadTest(); в следующем примере создает общий экземпляр, а не отдельный экземпляр. Пожалуйста, посоветуйте, спасибо!

class ThreadTest
{
  bool done;

  static void Main()
  {
    ThreadTest tt = new ThreadTest();   // Create a common instance
    new Thread (tt.Go).Start();
    tt.Go();
  }

  // Note that Go is now an instance method
  void Go() 
  {
     if (!done) { done = true; Console.WriteLine ("Done"); }
  }
}

EDIT: Пример из http://www.albahari.com/threading/#_Introduction, который демонстрирует, как делиться данными между потоками.

EDIT2: Мой вопрос точно, почему "экземпляр является общим для обоих потоков"

Ответы [ 3 ]

5 голосов
/ 30 августа 2010

Неясно, что вы подразумеваете под «общим экземпляром», но конструктор определенно создает новый экземпляр. Метод Go выполняется дважды, один раз в новом потоке и один раз в основном потоке.

Возможно, автор кода имел в виду, что экземпляр является общим для обоих потоков, потому что оба потока вызывают метод Go для одного и того же экземпляра.

Внутри метода Go есть состояние гонки. Он может непредсказуемо напечатать «Готово» дважды.

1 голос
/ 11 июня 2016

6 лет спустя, и я здесь, потому что я прочитал тот же раздел этой книги.Пример в книге, непосредственно предшествующей тому, который вы упомянули, показывает (статический). Идет выполнение в новом анонимном потоке, а затем снова отдельно в локальном контексте.

new Thread (Go).Start();
Go();

Пример в вашем вопросесначала создает экземпляр TT, а также меняет .Go с статического метода на метод экземпляра.

ThreadTest tt = new ThreadTest();
new Thread (tt.Go).Start();
tt.Go();

Так что теперь, когда .Go отправляется в новый поток для выполнения, отправляется то, что отправляется.Копия tt метода (вместо статического метода .Go), которая также выполняется локально сразу после строки 3. Поскольку оба выполнения .Go принадлежат tt, они также используют копию tt done.Афаик, вот почему автор называет эти данные «общими», потому что теперь они могут быть доступны обоим потокам.

В сторону: я все еще не уверен в некоторых аспектах создания потоков самостоятельно.Для меня загадка - что именно происходит с tt при выполнении new Thread (tt.Go).Start(); ... tt был создан в исходном потоке, но теперь он живет в обоих?Применяется ли здесь byref / byval или что-то еще происходит?Точнее сказать, что объект tt на самом деле не «жив» или «принадлежит» ни одному из потоков, а скорее находится в куче, и поэтому оба потока должны иметь к нему доступ?

1 голос
/ 30 августа 2010

Если вы имеете в виду, что оба вызова tt.Go совместно используют переменную done, то это, конечно, произойдет. Вы вызываете метод для того же объекта, только тот, который происходит в основном потоке, а другой - в отдельном потоке.

Вы всегда создаете только один экземпляр ThreadTest, но вызываете Go дважды, поэтому оба вызова должны выполняться для одного и того же объекта!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...