use*_*857 10 c# singleton thread-safety
我有一个类似于此的单例类
public class Singleton
{
private static Singleton m_instance;
private Timer m_timer;
private static List<CustomObject> m_cacheObjects;
private Singleton()
{
m_cacheObjects = new List<CustomObject>();
m_timer= new Timer(MyTimerCallBack,
null,
TimeSpan.FromSeconds(60),
TimeSpan.FromSeconds(60));
}
public static Singleton Instance
{
get
{
if (m_instance == null)
{
m_instance = new Singleton();
}
return m_instance;
}
}
private void MyTimerCallBack(object state)
{
//******** Update the list by interval here ******************
m_cacheObjects = UpdateTheList();
}
public void CallMe()
{
foreach (CustomObject obj in m_cacheObjects)
{
// do something here based on obj
// The question is, does the m_cacheObjects is thread safe??
// what happen if the m_cacheObjects is changed
// during the loop interation?
}
}
}
Run Code Online (Sandbox Code Playgroud)
CallMe方法将由Web服务调用:
[WebMethod]
public void CallMeWebService()
{
Singleton.Instance.CallMe();
}
Run Code Online (Sandbox Code Playgroud)
问题:1)m_cacheObjects是否是线程安全的?如果在循环交互期间(在CallMe()中)m_cacheObjects被更改(因为计时器)会发生什么?
2)在调用Webservice CallMeWebService()时是否会创建新线程?
1:不,静态列表不是自动线程安全的; 你必须m_cacheObjects手动保护
2:这是一个实现细节; 乍一看,它似乎将自己暴露为同步方法,但它如何做到完全取决于它
实际上,你的静态初始化也不是线程安全的; 我可以强制使用两个不同Singleton实例的场景.生产它需要重复,但它会发生.
坦率地说,除非你有充分的理由不这样做,否则最简单但最安全的单身人士模式就是:
private static readonly Singleton m_instance = new Singleton();
Run Code Online (Sandbox Code Playgroud)
这是关于如何以线程安全的方式实现单例模式的非常好的资源:http://msdn.microsoft.com/en-us/library/ff650316.aspx
public sealed class Singleton
{
private static volatile Singleton instance;
private static object syncRoot = new Object();
private Singleton() {}
public static Singleton Instance
{
get
{
if (instance == null)
{
lock (syncRoot)
{
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这只是确保永远不会有多个实例。您还需要为您的自定义方法应用锁定。
public void CallMe()
{
lock (syncRoot)
{
foreach (CustomObject obj in m_cacheObjects)
{
// do something here based on obj
}
}
}
Run Code Online (Sandbox Code Playgroud)
//using System.Runtime.CompilerServices;
private static volatile Singelton _instance;
public static Singelton Instance
{
[MethodImpl(MethodImplOptions.Synchronized)]
get
{
if (_instance == null)
{
_instance = new Singelton();
}
return _instance;
}
}
Run Code Online (Sandbox Code Playgroud)
说明:
[MethodImpl(MethodImplOptions.Synchronized)]这将告诉编译器对"Instance"的访问是"已同步",因此系统会关注对此Parameter的调用.
这是线程安全的.
编辑:(另外,"Lock()"示例不安全!因为,你可以通过"Monitor.Exit(Singleton);"来禁用线程安全性
| 归档时间: |
|
| 查看次数: |
11766 次 |
| 最近记录: |