#c# #new-operator
#c# #new-operator
Вопрос:
namespace usenewagain
{
class Program
{
public static Thread thread1;
static void Main(string[] args)
{
thread1 = new Thread(() => threadsDelegate(TimeSpan.FromMinutes(1), 1) );
thread1.Start();
while(thread1.IsAlive)
{
}
thread1 = new Thread(() => threadsDelegate(TimeSpan.FromMinutes(2), 1));
thread1.Start();
while(thread1.IsAlive)
{
}
Console.WriteLine("Done...");
Console.ReadLine();
}
}
}
Насколько я могу судить по этой консольной программе, использование new в thread1 снова является законным, и, похоже, оно работает нормально. Насколько я могу судить, thread1 перезаписывается вторым вызовом new . Могу ли я получить некоторую проверку того, что повторное использование new допустимо таким образом?
Спасибо…
Ответ №1:
Да и нет.
каждый раз, когда вы используете new
, вы создаете новый объект и сохраняете ссылку на этот объект в своей переменной.
Итак
thread1 = new Thread(...)
создает новый экземпляр Thread
и сохраняет ссылку на этот экземпляр thread1
.
когда вы делаете это во второй раз, вы создаете второй экземпляр Thread
, но не уничтожаете старый. Вы просто перезаписываете ссылку, которая является просто «адресом» потока.
однако у вас есть сборщик мусора, который очистит первый поток, если у вас нет ссылок на него, поэтому, если где-то останется ссылка на ваш первый поток (например, если вы назначили его какой-либо другой переменной), сбор мусора не будет.
Комментарии:
1. Так что, возможно, запуск GC. Сбор может помочь тогда?
2. @user2209542 нет, это не поможет. Даже если вы запустите GC. Сбор, если все еще есть ссылка на поток, он не будет собран. Лично мне нравится избегать ручной сборки мусора и позволять сборщику мусора делать это.
3. Таким образом, нет другой ссылки только на thread1, поэтому вы должны сказать, что проблемы нет, и thread1 в этом случае будет собираться мусор.
Ответ №2:
Если под «Допустимым» вы подразумеваете «Будет компилироваться» и «Перезапишет мою переменную», то да, это допустимо.
Однако это опасно. Перезаписывая переменную, вы теряете любую ссылку на нее, если хотите выполнить Join
с ней или любую другую операцию. Если вы ожидаете, пока поток Join
завершится , что, кстати, предпочтительнее вашего ожидания вращения, это безопасная операция.
Комментарии:
1. * спин-ожидание. Блокировка вращения — это нечто другое.
2. @dcastro, отличная точка зрения. Блокировка вращения используется для предотвращения условий гонки. Ожидание вращения просто тратит циклы процессора на ожидание завершения чего-либо еще.