多线程应用程序中的单例类,锁定建议
我有在多个线程中共享的单例类。为了防止多重访问问题,我在访问类的一个或另一个属性时使用 Lock 方法。问题是是否可以改进代码并将 Lock 方法放入单例类中,而不是每次在代码中访问类属性时都将其放入?
/* 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++;
}
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++;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
ServerStatus
应该维护自己的同步,而不是此类的外部客户端。话虽这么说,您需要重构ServerStatus
并创建一些线程安全(带锁定)的方法:删除这些属性:
public List;活塞队列 { 得到;放; }
因为即使您可以锁定这些属性,您也无法控制客户端在获取实际的PistonQueue
后执行的操作。...并替换为以下方法(抱歉伪代码,我今天懒得去思考):
ServerStatus
should maintain its own synchronization, not external clients of this class. That being said, you'll need to refactorServerStatus
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 actualPistonQueue
....and replace with methods such as (sorry pseudo-code, I can't be bothered to think today):
如果您感兴趣的话,这是我使用的单例线程安全模式:
This is the singleton thread-safe pattern I use in case you are interested:
恕我直言,这是单例中线程安全锁定的最终解决方案。来自它(列表中的第五个):
IMHO, this is the definitive solution for thread-safe locking in a singleton. From it (fifth on the list):
这是相当常见的。与每个属性访问上的外部锁相比,在 getter/setter 中锁定/解锁更安全(您不能忘记这样做),也更方便(该锁不必在您使用该属性的任何地方都可以直接访问) 。
平均值,
马丁
This is fairly common. Locking/unlocking in the getters/setters is much safer, (you cannot forget to do it), and more convenient, (the lock does not have to be directly accessable everywhere you use the property), than an external lock on every property access.
Rgds,
Martin