线程安全问题

时间:2011-01-20 07:44:55

标签: c# .net multithreading thread-safety

我知道我们需要为类中的静态成员变量处理线程安全。我们需要担心实例成员变量吗?

3 个答案:

答案 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.