给定以下类,并假设打印列表需要很长时间才能运行,如果线程1调用PrintList(),然后线程2在运行时调用ClearList,会发生什么?
我们不是在修改集合,而只是更改引用以指向堆中的其他位置。那么枚举继续起作用吗?如果是这样,是因为_someList引用的副本被放到方法的堆栈框架上了吗?
public class foo()
{
private static List<string> _someList;
public void ClearList()
{
_someList = null;
}
public void PrintList()
{
foreach(var item in _someList)
{
Console.Print(item);
}
}
}
将发生两种非常可预见的事情之一。在某个时间点,第一个线程将评估变量_someList
的值,即对列表的引用。如果在第二个线程清除它之前发生这种情况,那么它将遍历该列表并打印结果。如果第二个线程碰巧在进入foreach
循环之前清除了列表,那么您将得到一个null引用异常。
注意,对引用类型的变量的读写是原子的,因此我们知道将变量设置为null
不会导致无效的引用。第一个线程将遵循原始引用或null
,没有“读取垃圾引用”的可能性。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句