假设我有如下代码:
int Main()
{
if (true)
{
new Thread(()=>
{
doSomeLengthyOperation();
}).Start();
}
while (true)
{
//do nothing
}
}
有两个线程,我将调用Main线程执行Main()函数的线程,并在“if”测试中将线程作为线程A新建 .
我的问题是,线程A什么时候被销毁? do doSomeLenghtyOperation()能够完成吗?
由于没有指向线程A的引用,它是否会被标记为垃圾收集的候选者:
-
"new Thread().Start()"语句本身完成后立即?
-
退出"if(true)"范围后立即?
-
doSomeLengthOperation()运行完成后?
-
从不?
我看到的所有示例都是Main()持有引用,然后主线程在退出之前等待与线程A连接 . 我很好奇上面代码的生命周期是什么 .
提前致谢!
4 回答
Thread
对象一旦不再使用就会有资格进行垃圾收集,即在调用Start
方法后立即进行 . (但是不会立即收集,因为垃圾收集器在特定时间运行 . )但是,实际线程不依赖于
Thread
对象,即使收集了Thread
对象,它也将继续运行 .如果在main方法退出时线程仍在运行,则应用程序将不会在线程完成之前结束,除非您已将该线程标记为后台线程 .
单词“thread”在这里可能意味着几件事:
System.Threading.Thread对象(由
new Thread()
创建),CLR线程(托管线程),
OS线程(非托管线程) .
一旦Start()方法完成,线程对象将成为GC的候选对象,因为没有更多对它的引用 .
当doSomeLengthyOperation()运行时,托管线程将保持活动状态 .
引用微软MVP的James Kovacs的article:
如果您想自己试验,本文还包含一些有用的代码示例 .
理论上,操作系统线程与托管线程没有一对一的关系 . 从MSDN:
但实际上,CLR线程maps directly to a Windows thread today .
当
doSomeLengthyOperation
完成时 .是的,即使主线程存在,因为它不是后台线程 . 如果在主线程存在时启动线程之前将IsBackground属性设置为
true
,则此线程也将停止 .这是一个很好的问题!线程肯定会完成,你可以自己尝试一下 . 但是如果你在while中调用GC.Collect()会很有趣 . 根据Richter的C#通过CLR,它将被垃圾收集 .
UPDATE
我相信它不会被垃圾收集,因为Thread.CurrentThread通过引用将它保存在内存中 .