Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Singleton Class in multithreading app, locking suggestion

I have singleton class which is shared in several threads. To prevent multiple access issues I use Lock method when accessing one or another property of the class. The question would be is it possible to improve code and put Lock method inside singleton class rather than putting it every time when the class property is accessed in code?

/* 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++;
}
like image 523
Tomas Avatar asked Jun 22 '11 12:06

Tomas


People also ask

How do you handle singleton in multithreading?

Thread Safe Singleton in Java Create the private constructor to avoid any new object creation with new operator. Declare a private static instance of the same class. Provide a public static method that will return the singleton class instance variable.

Can we use singleton class in multithreading?

Thread Safe Singleton: A thread safe singleton is created so that singleton property is maintained even in multithreaded environment. To make a singleton class thread safe, getInstance() method is made synchronized so that multiple threads can't access it simultaneously.

Is singleton class is thread safe?

Is singleton thread safe? A singleton class itself is not thread safe. Multiple threads can access the singleton same time and create multiple objects, violating the singleton concept. The singleton may also return a reference to a partially initialized object.

What is singleton lock?

Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code. Singleton has almost the same pros and cons as global variables. Although they're super-handy, they break the modularity of your code.


3 Answers

ServerStatus should maintain its own synchronization, not external clients of this class. That being said, you'll need to refactor ServerStatus and create a few thread-safe (with locking) methods:

Remove these properties: public List<string> PistonQueue { get; set; } since even though you can lock inside these properties, you can't control what clients do once they get a hold of the actual PistonQueue.

...and replace with methods such as (sorry pseudo-code, I can't be bothered to think today):

public PistonQueueAdd(string fullPath)
{
    lock(_serverStatusSyncRoot)
    {
        // ...
    }
}
like image 157
Chris O Avatar answered Oct 16 '22 12:10

Chris O


This is the singleton thread-safe pattern I use in case you are interested:

    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
}
like image 21
Dummy01 Avatar answered Oct 16 '22 11:10

Dummy01


IMHO, this is the definitive solution for thread-safe locking in a singleton. From it (fifth on the list):

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();
    }
}
like image 26
Yuck Avatar answered Oct 16 '22 12:10

Yuck