鉴于以下类并假设打印列表需要很长时间才能运行,如果线程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);
}
}
}
答案 0 :(得分:6)
两个非常可预测的事情中的一个将会发生。在某个时间点,第一个线程将评估变量_someList
到其值,即对列表的引用。如果在第二个线程清除它之前发生这种情况,那么它将遍历该列表并打印结果。如果第二个线程在到达foreach
循环之前清除了列表,那么您将获得一个空引用异常。
请注意,对引用类型的变量的读取和写入是可观察的原子,因此我们知道将变量设置为null
会导致无效的引用;第一个线程将观察原始引用或null
,没有&#34;读取垃圾引用&#34;可能性。