使用C#示例锁定以使类线程安全或者此类线程是否安全?

Chr*_*end 4 c# locking thread-safety

我正在尝试调查锁定以创建线程安全类并有几个问题.鉴于以下课程:

    public class StringMe 
    {
        protected ArrayList  _stringArrayList = new ArrayList();
        static readonly object _locker = new object();

        public void AddString(string stringToAdd)
        {
            lock (_locker) _stringArrayList.Add(stringToAdd);
        }

        public override string ToString()
        {
            lock (_locker)
            {
return string.Join(",",string[])_stringArrayList.ToArray(Type.GetType("System.String")));
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

1)我是否成功地使AddString和ToString线程安全?

2)在我创建的ToString方法中是否有必要锁定它以使其线程安全?

3)是否只需要修改需要锁定的数据的方法,或者是否需要锁定读取和写入操作以使其线程安全?

非常感谢您的参与!

Jon*_*eet 13

不,你没有让这些调用线程安全 - 因为该_stringArrayList字段受到保护.子类可以做任何他们用它喜欢同时AddStringToString被调用.

例如(正如其他答案声称您的代码线程安全的.)

public class BadStringMe : StringMe
{
    public void FurtleWithList()
    {
        while (true)
        {
            _stringArrayList.Add("Eek!");
            _stringArrayList.Clear();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

BadStringMe bad = new BadStringMe();
new Thread(bad.FurtleWithList).Start();
bad.AddString("This isn't thread-safe");
Run Code Online (Sandbox Code Playgroud)

首选私有字段 - 它可以更容易推理您的代码.

另外:

  • 不想List<T>ArrayList这些天
  • 你是一个带锁定静态出于某种原因变量......所以,即使你已经得到的多个实例StringMe,只有一个线程可以在AddString同时在总
  • 使用typeof(string)比清洁更清洁Type.GetType("System.String")

3)是否只需要修改需要锁定的数据的方法,或者是否需要锁定读取和写入操作以使其线程安全?

所有,假设可能有一些操作.如果所有内容都只是读取,那么您不需要任何锁定 - 但是否则您的读取线程可以读取数据结构中的两位数据,这些数据在两者之间进行了修改,即使只有一个写入线程.(还要考虑记忆模型的考虑因素.)