繁体   English   中英

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

[英]Locking to make a class threadsafe with a C# example or is this class threadsafe?

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

    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")));
            }
        }
    }

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

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

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

非常感谢您的参与!

不,您没有使这些调用成为线程安全的 - 因为_stringArrayList字段受到保护。 在调用AddStringToString子类可以使用它做任何他们喜欢的事情。

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

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

然后:

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

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

另外:

  • 这些天首选List<T>ArrayList
  • 你出于某种原因使用静态变量锁定...所以即使你有几个StringMe实例, StringMe只有一个线程可以在AddString
  • 使用typeof(string)Type.GetType("System.String")更清晰

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

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

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

是的,如果您将_stringArrayList更改为私有

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

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

读和写。

对所有三个都是肯定的(即读/写到最后一个)。

但还有更多:

您将锁定对象设置为static ,而您保护的数据是每个实例字段。 这意味着StringMe所有实例都是相互保护的,尽管它们具有不同的数据(即_stringArrayList实例)。 对于您给出的示例,您可以从_locker删除static修改器。 更确切地说,您通常要为一组数据定义“锁定”,或者为了保留更好的不变量 通常,锁的生命周期(和范围)应该等于数据的生命周期(和范围)。

此外,为了更好地衡量,您保护的数据的可见性不应高于锁定。 在您的示例中,派生实现可以在不获取锁定的情况下更改_stringArrayList (因为它受到保护),从而打破了不变量。 我会让它们都是private ,如果必须的话,只将_stringArrayList通过(正确锁定)方法暴露给派生类。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM