单线程类在多线程应用程序中,锁定建议

时间:2011-06-22 12:23:03

标签: c# class locking thread-safety

我有单个类,它在多个线程中共享。为了防止多个访问问题,我在访问类的一个或另一个属性时使用Lock方法。问题是是否有可能改进代码并将Lock方法放在singleton类中,而不是每次在代码中访问类属性时都将它放入?

/* Class code*/
   public class ServerStatus
    {


        private static ServerStatus _instance;
        public static ServerStatus Instance
        {
            get { return _instance ?? (_instance = new ServerStatus()); }
            set { _instance = value; }
        }

        ServerStatus()
        {
            PistonCount = 0;
            PistonQueue = new List<string>();
            ErrorList = new List<string>();
        }




        public int PistonCount { get; set; }

        public List<string> PistonQueue { get; set; }

        public List<string> ErrorList { get; set; }
    }



 /*Code for accessing class properties*/
private static readonly object Locker = new object();    
/*Skip*/

lock (Locker)
{
 ServerStatus.Instance.PistonQueue.Add(e.FullPath);
}
    /*Skip*/

lock (Locker)
{
    ServerStatus.Instance.PistonCount++;
}

4 个答案:

答案 0 :(得分:4)

ServerStatus应保持自己的同步,而不是此类的外部客户端。话虽这么说,你需要重构ServerStatus并创建一些线程安全(带锁定)方法:

删除这些属性:public List<string> PistonQueue { get; set; },因为即使您可以锁定这些属性,也无法控制客户端获取实际PistonQueue后所执行的操作。

...并替换为诸如(抱歉伪代码,我今天无法想到)这样的方法:

public PistonQueueAdd(string fullPath)
{
    lock(_serverStatusSyncRoot)
    {
        // ...
    }
}

答案 1 :(得分:3)

这是我感兴趣的单例线程安全模式:

    public class DataAccess
{
    #region Singleton

    private static readonly object m_SyncRoot = new Object();

    private static volatile DataAccess m_SingleInstance;

    public static DataAccess Instance
    {
        get
        {
            if (m_SingleInstance == null)
            {
                lock (m_SyncRoot)
                {
                    if (m_SingleInstance == null)
                        m_SingleInstance = new DataAccess();
                }
            }

            return m_SingleInstance;
        }
    }

    private DataAccess()
    {
    }

    #endregion
}

答案 2 :(得分:2)

恕我直言,这是the definitive solution,用于单例中的线程安全锁定。从它(列表中的第五位):

public sealed class Singleton
{
    private Singleton()
    {
    }

    public static Singleton Instance { get { return Nested.instance; } }

    private class Nested
    {
        // Explicit static constructor to tell C# compiler
        // not to mark type as beforefieldinit
        static Nested()
        {
        }

        internal static readonly Singleton instance = new Singleton();
    }
}

答案 3 :(得分:0)

这很常见。 getter / setter中的锁定/解锁更加安全,(你不能忘记这样做),并且更方便,(锁不必在你使用属性的任何地方直接访问),而不是每个属性访问的外部锁

RGDS, 马丁