关于C#的单例模式实现方法

百世经纶一页书 2013-06-05 09:14:02
之前使用单例模式一直定义如下:

public partial class Personnel
{
static volatile Personnel _instance = null;
static readonly object Padlock = new object();
private readonly DaoManager _daoManager = null;
private readonly ICommonDao _commonDao = null;

private Personnel()
{
_daoManager = ServiceConfig.GetInstance().DaoManager;
_commonDao = _daoManager[typeof(ICommonDao)] as ICommonDao;
}
/// <summary>
/// 获取单一实例
/// </summary>
/// <returns></returns>
public static Personnel GetInstance()
{
if (_instance == null)
{
lock (Padlock)
{
if (_instance == null)
{
_instance = new Personnel();
}
}
}
return _instance;
}
}

这几天做一个项目,发现我们项目经理定义单例模式是这么做的:

public partial class Personnel
{
private static Personnel _instance = new Personnel () ;
static readonly object Padlock = new object();
private readonly DaoManager _daoManager = null;
private readonly ICommonDao _commonDao = null;

private Personnel()
{
_daoManager = ServiceConfig.GetInstance().DaoManager;
_commonDao = _daoManager[typeof(ICommonDao)] as ICommonDao;
}
/// <summary>
/// 获取单一实例
/// </summary>
/// <returns></returns>
public static Personnel GetInstance()
{
return _instance;
}
}

请问这两种定义单例模式的方法有没有什么差别呢?
...全文
950 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
microdust1982 2015-12-31
  • 打赏
  • 举报
回复
第二种怎么没有判断。窗口关了之后再打开不会报错?
衣舞晨风 2015-12-15
  • 打赏
  • 举报
回复
引用 7 楼 lifeilin6671 的回复:
[quote=引用 5 楼 sqlchen 的回复:] 如果实例化对象比较耗时/耗系统资源,或者程序运行并不一定用到的话,会采用lazy load,即第一种方式。 通常来说如果该对象总要用到或者访问次数较多,那么干脆就用第二种方式,由于这种方式省掉了判断和锁定处理,效率会高一些。
第二种在高并发的情况下会不会出现问题呢? 也就是说在高并发的情况下类的静态构造函数会不会被多次调用呢?[/quote] 可以看看 CLR via C#
  • 打赏
  • 举报
回复
引用 16 楼 lifeilin6671 的回复:
那么第一种的两次判断和一次锁定对性能有没有影响呢?
没有必要纠结这个“影响”问题。如果一定要研究,那么你就自己写出测试来。
  • 打赏
  • 举报
回复
引用 7 楼 lifeilin6671 的回复:
第二种在高并发的情况下会不会出现问题呢? 也就是说在高并发的情况下类的静态构造函数会不会被多次调用呢?
你信吗?“静态构造函数会被多次调用”?
wangjj89621 2013-06-06
  • 打赏
  • 举报
回复
引用 7 楼 lifeilin6671 的回复:
[quote=引用 5 楼 sqlchen 的回复:] 如果实例化对象比较耗时/耗系统资源,或者程序运行并不一定用到的话,会采用lazy load,即第一种方式。 通常来说如果该对象总要用到或者访问次数较多,那么干脆就用第二种方式,由于这种方式省掉了判断和锁定处理,效率会高一些。
第二种在高并发的情况下会不会出现问题呢? 也就是说在高并发的情况下类的静态构造函数会不会被多次调用呢?[/quote] 木有问题
gengchenhui 2013-06-06
  • 打赏
  • 举报
回复
记得好像最简单的就是 publice static readonly Singleton instanse=new Singleton(); 然后构造函数私有就可以了。
viena 2013-06-06
  • 打赏
  • 举报
回复
第一种是Java的写法照搬过来的; 而.NET的静态是线程安全的,第二种在.NET中无任何问题
  • 打赏
  • 举报
回复
引用 19 楼 sp1234 的回复:
[quote=引用 16 楼 lifeilin6671 的回复:] 那么第一种的两次判断和一次锁定对性能有没有影响呢?
没有必要纠结这个“影响”问题。如果一定要研究,那么你就自己写出测试来。[/quote] 这种类初始化的测试还真不会写呢?能不能提供一个思路呢?
niss 2013-06-05
  • 打赏
  • 举报
回复
第一种好,只有一种极端情况可能比第二种慢,就是在没有初始化的情况下瞬间打入超多的请求,导致超多的lock等待,除此之外,所有的请求都会在第一层的==null的判断就结束了,没有进入lock的必要
gomoku 2013-06-05
  • 打赏
  • 举报
回复
引用 11 楼 lifeilin6671 的回复:
如果我获取的单例模式可能会根据传入的参数不同而初始化不同的类的实例,是不是第二种就不能用了呢?
对。 不过这种情况,也不好说是传统意义上的单例。
  • 打赏
  • 举报
回复
引用 9 楼 gomoku 的回复:
1、安全上,一样安全。CLR在初始化类的时候,已经加锁了。所以第二种也是安全的。 2、延迟加载上,两种方法都会延迟加载。区别是: 第一种方法在第一次调用Personnel.GetInstance()的时候加载; 第二种方法在第一次用到Personnel类的时候加载。 一般来说,如果没有特殊需求,第二种方法比较流行。一是写法简单,二是不需要加锁。
如果我获取的单例模式可能会根据传入的参数不同而初始化不同的类的实例,是不是第二种就不能用了呢?
ariesget 2013-06-05
  • 打赏
  • 举报
回复
没啥差吧,要我就用第2种了。简单方便,没必要做一些没用的判断操作。
  • 打赏
  • 举报
回复
引用 15 楼 tcmakebest 的回复:
第一种是用不到就不会创建,比较省内存 第二种是只要调用到任何静态方法,都会创建实例 个人认为第一种好一些。
那么第一种的两次判断和一次锁定对性能有没有影响呢?
gomoku 2013-06-05
  • 打赏
  • 举报
回复
1、安全上,一样安全。CLR在初始化类的时候,已经加锁了。所以第二种也是安全的。 2、延迟加载上,两种方法都会延迟加载。区别是: 第一种方法在第一次调用Personnel.GetInstance()的时候加载; 第二种方法在第一次用到Personnel类的时候加载。 一般来说,如果没有特殊需求,第二种方法比较流行。一是写法简单,二是不需要加锁。
Null_Reference 2013-06-05
  • 打赏
  • 举报
回复
最近遇到,学习!
  • 打赏
  • 举报
回复
引用 5 楼 sqlchen 的回复:
如果实例化对象比较耗时/耗系统资源,或者程序运行并不一定用到的话,会采用lazy load,即第一种方式。 通常来说如果该对象总要用到或者访问次数较多,那么干脆就用第二种方式,由于这种方式省掉了判断和锁定处理,效率会高一些。
第二种在高并发的情况下会不会出现问题呢? 也就是说在高并发的情况下类的静态构造函数会不会被多次调用呢?
V0lD 2013-06-05
  • 打赏
  • 举报
回复
第一种考虑到并发,多线程访问的问题,以前老师也推荐这么写,实际中可能并发的情况不会出现,我们开发中个个都写第二种
sqlchen 2013-06-05
  • 打赏
  • 举报
回复
如果实例化对象比较耗时/耗系统资源,或者程序运行并不一定用到的话,会采用lazy load,即第一种方式。 通常来说如果该对象总要用到或者访问次数较多,那么干脆就用第二种方式,由于这种方式省掉了判断和锁定处理,效率会高一些。
  • 打赏
  • 举报
回复
引用 1 楼 viena 的回复:
第二种好些。lazyload么必要
引用 2 楼 linuxca 的回复:
主要是加锁的问题,并发不多的话,没有问题,否则前一种好些.
引用 3 楼 guwei4037 的回复:
第一种好。第二种就是直接定义了一个静态全局变量。
第一种在普遍的设计模式书上都是这么定义的。 第二种我还是第一次见, 但是不知道这两种方式在高并发的环境下哪种更安全些呢?
加载更多回复(6)

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧