由于代码的原子操作外观,可以将以下内容视为线程安全。 我主要担心的是,如果列表需要重新调整大小,它会在重新调整大小时变得非线程安全。
List<int> list = new List<int>(10);
public List<int> GetList()
{
var temp = list;
list = new List<int>(10);
return temp;
}
TimerElapsed(int number)
{
list.Add(number);
}
答案 0 :(得分:4)
没有。 List<T>
明确documented 不是线程安全的:
在List上执行多个读取操作是安全的,但如果在读取集合时修改了集合,则可能会出现问题。要确保线程安全,请在读取或写入操作期间锁定集合。要使多个线程可以访问集合以进行读写,您必须实现自己的同步。对于具有内置同步的集合,请参阅System.Collections.Concurrent命名空间中的类。有关本质上线程安全的替代方法,请参阅ImmutableList类。
答案 1 :(得分:3)
您的代码和List<T>
都不是线程安全的。
根据documentation列表,该列表不是线程安全的。您的代码不是线程安全的,因为它缺乏同步。
考虑同时调用GetList
的两个线程。假设第一个帖子在设置temp
后立即被抢先一步。现在第二个线程设置自己的temp
,替换list
,并让GetList
函数运行完成。当第一个线程继续时,它将返回第二个线程刚刚返回的list
。
但这不是全部!如果第三个线程在第二个线程完成之后但在第一个线程完成之前调用了TimerElapsed
,则它会在一个即将被覆盖而没有跟踪的列表中放置一个值。因此,不仅多个线程返回相同的数据,而且您的一些数据也将消失。
答案 2 :(得分:1)
没有。它不是线程安全。尝试使用System.Collections.Concurrent
namespace
答案 3 :(得分:1)
如前所述,List<T>
不是线程安全的。您可以查看Concurrent
命名空间中的备选项,可能使用ConcurrentBag
,或者Dean Chalk Fast Parallel ConcurrentList<T> Implementation
上有一篇文章。
答案 4 :(得分:0)
它不是线程安全的,因为在GetList方法的第一行之间可以有一个上下文切换,它转换为TimerElapsed方法。这将在不同的场景上产生不一致的结果。另外,正如其他用户已经提到的那样,List类不是线程安全的,你应该使用System.Collections.Concurrent等价物。
答案 5 :(得分:-1)
只读是线程安全,而不是写作。