我知道我们需要为类中的静态成员变量处理线程安全。我们需要担心实例成员变量吗?
答案 0 :(得分:4)
是的,你应该关心,因为同一个类实例方法可以作为回调传递给多个线程。例如:
var instance = new Foo();
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod);
ThreadPool.QueueUserWorkItem(instance.SomeInstanceMethod);
现在需要同步实例方法,因为在这种情况下,共享状态就是实例本身。
答案 1 :(得分:4)
这取决于您是否希望您的类型是线程安全的...以及您的意思。
大多数时候,我认为记录类型不是线程安全是完全合理的,但可以通过适当的同步从不同的线程安全地使用。大多数.NET类型都属于这一类。
那你通常可以确保只有“协调”对象需要担心同步,而不是锁定每个方法和属性 - 这是一个痛苦的策略,并没有真正解决更广泛的同步问题你无论如何都可能会遇到。
当然,从多个线程中使用自然的类型 - 专门设计用于启用并发或服务定位器等的类型应该是线程安全的 - 并且应该记录在案。同样,完全不可变的类型开始时自然是线程安全的。
最后,还有一个重要的问题就是“线程安全”。您应该阅读Eric Lippert's blog post关于此事的内容,以澄清您应该考虑和记录的内容。
答案 2 :(得分:0)
请考虑以下代码:
public void Execute()
{
Task.Factory.StartNew(Iterrate);
Task.Factory.StartNew(Add);
}
private List<int> _list = Enumerable.Range(1, 10).ToList();
private void Iterrate()
{
foreach (var item in _list)
{
Console.WriteLine(item);
}
}
private void Add()
{
_list.Add(_list.Count);
}
此代码将导致(大多数时间):
InvalidOperationException: Collection was modified; enumeration operation may not execute.