我需要一个以ReadOnlyCollection为参数的并发方法的锁吗

本文关键字:并发 方法 参数 一个以 ReadOnlyCollection | 更新日期: 2023-09-27 18:29:47

假设一个方法是这样的。

Class MyClass
public string ConcatenateList(ReadOnlyCollection<string> aList)
{
  var result = new StringBuilder();
  foreach (string s in aList)
  {
     result.Append(", " + s);
  }
  return result.ToString();
} 

下面是一个调用方生成只读列表以传递给MyClass.ConcateateList方法的示例。

var list = new List<string>(){"hello","world"};
var readOnlyList = new ReadOnlyCollection<string>(list);

虽然该方法确实无法修改列表,但要求调用方能够在执行该方法时修改基础列表。此外,方法必须是并发的

2个问题:

(1) 鉴于上述要求,该方法中是否存在竞赛条件?就我所见,没有。ThreadA永远不会读取或写入ThreadB的StringBuilder,因此不存在并发问题,因此不需要锁。是吗?

(2) 是否会出现并发可能导致返回字符串出现意外结果的情况?一个例子是:即使在执行过程中将"howdy"添加到仅由ThreadB拥有的列表中,ThreadA也会返回",hello,world,howdy"。这会发生吗?

我试图理解,在给定并发性的情况下,ConcatenateList()是否必须是一个"纯函数",即该方法保证其参数"aList"在整个方法执行过程中永远不会被修改(由其自身或调用方)?

提前感谢您的想法!

我需要一个以ReadOnlyCollection为参数的并发方法的锁吗

ReadOnlyCollection不会将构造函数中提供的列表中的数据复制到只公开只读成员的新集合中。相反,它只封装所提供的IList,并且只公开它的只读成员

这意味着ReadOnlyList访问的内存与代码中原始List引用访问的内存相同,需要使用适当的同步才能确保安全。在本例中,由于没有同步,当另一个线程访问只读列表时,调用者对底层列表的修改可能会导致任意数量的未定义行为。