***** 关于Singleton(单件模式)的静态变量的执行问题,走过路过的请进来看看

badboy168 2006-07-14 09:05:12
程序源码如下
using System;
using System.Data;
using System.Threading;

namespace Singleton_Pattern
{
public sealed class CountSingleton
{
static readonly CountSingleton iuCount = new CountSingleton();
private int totNum = 0;

private CountSingleton()
{}

public void Add()
{
this.totNum++;
}

public int GetValue
{
get
{
return this.totNum;
}
}

public static CountSingleton Instance
{
get
{
return iuCount;
}
}
}

public class EntryProgram
{
public static void Main()
{
for(int i = 0; i < 3; i++)
{
CountSingleton singleton = CountSingleton.Instance;
singleton.Add();
Console.WriteLine(singleton.GetValue);
}

Console.ReadLine();
}
}
}


我的问题
1.每一次执行for语句时CountSingleton类会依次执行以后语句
static readonly CountSingleton iuCount = new CountSingleton();
private int totNum = 0;

private CountSingleton()
{}

static readonly CountSingleton iuCount = new CountSingleton();

静态类的初始化执行了两次,是因为new CountSingleton();的原因才执行的两次吗,具体是什么原因

2.每1次以后再执行for语句时不再执行问题1中的变量初始化语句,直接返回CountSingleton.Instance属性提供的实例,为什么只有第一次才执行静态成员的初始化工作?
...全文
232 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
diandian82 2006-07-14
  • 打赏
  • 举报
回复
因为你只产生了一个对象。静态对象是属于类的,在程序执行前就初始化完了。在你的for语句中叶不会做任何初始化。
sungny 2006-07-14
  • 打赏
  • 举报
回复
1.你是如何确定的静态类的初始化执行了两次?
2.程序执行一次后CountSingleton实例已经放到内存,由于是static的所以第二次运行时没有执行初始化。
www_123du_com 2006-07-14
  • 打赏
  • 举报
回复
badboy168(物有所不足,智有所不明(Stay Hungry. Stay Fooli) ( ):
没有人会吗
---------------------------------
看到这句觉得不太爽!本来想不答了!

1.静态构造函数一定只执行一次。
2.静态成员的初始化实际上编译后包括在静态构造函数中,这也就变成了问题1。参看《.NET框架程序设计》
bineon 2006-07-14
  • 打赏
  • 举报
回复
我错了,被忽悠晕了。
楼主的代码没有问题
问题1:这几行代码指执行了一次。只是单步调试时发现黄色的箭头会有两次指向
static readonly CountSingleton iuCount = new CountSingleton();
但是这并不表示他执行了两次,后一次指向只是表示该语句执行完毕
问题2:static的东西,包括变量阿构造函数阿,都只执行一次。
kevin_gao 2006-07-14
  • 打赏
  • 举报
回复
单件模式,如此写据说也是可以的:
static readonly CountSingleton Instance = new CountSingleton();
kevin_gao 2006-07-14
  • 打赏
  • 举报
回复
楼主,你说“静态类的初始化执行了两次”是怎么得到的结论?我建议在构造函数里面打印东西出来看看到底初始化了几次。
kevin_gao 2006-07-14
  • 打赏
  • 举报
回复
楼主,你说“静态类的初始化执行了两次”是怎么得到的结论?我建议在构造函数里面打印东西出来看看到底初始化了几次。
bineon 2006-07-14
  • 打赏
  • 举报
回复
static CountSingleton iuCount = null;
bineon 2006-07-14
  • 打赏
  • 举报
回复
貌似上面的说错了。static的构造函数只会执行一次。
然后,单件模式,我见的是这样的写法:
static readonly CountSingleton iuCount = null;
public static CountSingleton Instance
{
get
{
if (iuCount == null)
iuCount = new CountSingleton();
return iuCount;
}
}
bineon 2006-07-14
  • 打赏
  • 举报
回复
badboy168(物有所不足,智有所不明(Stay Hungry. Stay Fooli) ( ) 信誉:100 2006-07-14 11:21:00 得分: 0
没有人会吗
----------------
明显挑衅,没必要的,很多人还是很热心的。

关于问题二,static是只会初始化一次的,包括static的构造函数
badboy168 2006-07-14
  • 打赏
  • 举报
回复
没有人会吗
www_123du_com 2006-07-14
  • 打赏
  • 举报
回复
建议看看《.NET框架程序设计》

首先,类的成员变量的初始化,如你的:
static readonly CountSingleton iuCount = new CountSingleton();
不管是静态还是非静态,最终都被放到了构造函数中(静态的放到静态构造函数最前面,非静态的放到普通构造函数最前面)
即编译后的代码等同于如下:
static readonly CountSingleton iuCount;
static CountSingliton()
{
iuCount = new CountSingleton();
//假如原本就有静态构造函数,那么其中的代码就在其后面
}
这样你就该明白为什么我解释的似乎跟你要的解释是两回事了。

你的写法就创建来说,是线程安全的。
上面的可以改一下:
static readonly CountSingleton iuCount = null;
public static CountSingleton Instance
{
get
{
if (iuCount == null)
{
lock (typeof(CountSingleton))
{
if (iuCount == null)
iuCount = new CountSingleton();
}
}
return iuCount;
}
}
这样就是线程安全的了。
badboy168 2006-07-14
  • 打赏
  • 举报
回复
刚才错了,不是30多分钟是两个小时,是我有点着急,不过还是要向大家道个谦
badboy168 2006-07-14
  • 打赏
  • 举报
回复
还有一个就是请问一下,我的这个写法是线程安全的吗?
badboy168 2006-07-14
  • 打赏
  • 举报
回复
也许我的那句让让大伙气氛了,但是在CSDN这样的论坛30多分钟没有回贴,说明什么??

To bineon(雪冬寒):
你在三楼的方法显然不是线程安全的,如果两上线程同时进行
if (iuCount == null)
iuCount = new CountSingleton();
return iuCount;
怎以办,不就违背了单件模式的定义了吗?


这两个问题我已经弄明白了,至于第一个问题楼上几位朋友还是没有搞清楚我说的两次是什么意思,我在这里解释一下
第一次执行static readonly CountSingleton iuCount = new CountSingleton();是因为这个类被第一次调用,当类中所有字段初始化以手才会执行构造方法,虽然iuCount是static修饰的,但他是new出来的对象,执行二次的原因是只执行了new CountSingleton();部份,仅在内存的stack区中分配一个块区域

110,502

社区成员

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

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

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