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++;
}
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.
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 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.
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.
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)
{
// ...
}
}
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
}
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();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With