这个List <t>属性是否是线程安全的?</t>

时间:2011-05-03 19:49:53

标签: c# list thread-safety

    private List<T> _T;
    private readonly object _syncLock = new object();

    private List<T> MyT
    {
        get
        {
            lock (_syncLock)
                return _T.ToList<T>();
        }
        set
        {
            lock (_syncLock)
                _T = value;
        }
    }

3 个答案:

答案 0 :(得分:2)

是。您已使用成员变量作为锁定并确保无法更改。这样可以正常工作。

答案 1 :(得分:2)

不,这不是线程安全的。请查看以下代码:

static MyClass<int> sharedInstance = ...;

// Create a list
var list = new List<int>();

// Share the list
sharedInstance.MyT = list;

// list is now shared, this call is not thread-safe.
list.Add(5);

问题是您允许使用者引用内部数据结构。您可以按如下方式解决此问题:

private List<T> MyT
{
    get
    {
        lock (_syncLock)
            return _T.ToList<T>();
    }
    set
    {
        var copy = value.ToList();

        lock (_syncLock)
            _T = copy;
    }
}

答案 2 :(得分:1)

是的,你似乎很安全。如果你看一下ToList()的定义,那就是:

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    return new List<TSource>(source);
}

所以基本上你要创建一个新列表,其中包含旧列表的元素,所有这些都在你提供的锁定下,从而为它提供了线程安全性。

现在,列表的CONTENTS在两个列表中都是相同的引用,因此它不能保护您不会改变列表中存储的原始对象,它只保护列表本身。