给定以下类并假设打印列表需要很长时间才能运行,如果线程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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
两个非常可预测的事情之一将会发生.在某个时间点,第一个线程将评估变量_someList值到其值,即对列表的引用.如果在第二个线程清除它之前发生这种情况,那么它将遍历该列表并打印结果.如果第二个线程在它到达foreach循环之前碰巧清除了列表,那么你将得到一个空引用异常.
请注意,对引用类型的变量的读取和写入是可观察的原子,因此我们知道将变量设置为null不会导致无效引用; 第一个线程将观察原始引用,或者null没有"读取垃圾引用"的可能性.
| 归档时间: |
|
| 查看次数: |
90 次 |
| 最近记录: |