录一室
录一事, 求一知, 本一意, 笃一行
博客园
::
首页
::
新随笔
::
联系
::
订阅
::
管理
posts - 6, comments - 50, trackbacks - 0
公告
本站所有文章均为原创,版权归本人所有,欢迎转载,但请注明出处。
昵称:
录一事流
园龄:
5年11个月
粉丝:
0
关注:
0
<
2006年2月
>
日
一
二
三
四
五
六
29
30
31
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
搜索
常用链接
我的随笔
我的评论
我的参与
最新评论
我的标签
最新随笔
1. 安装配置支持中文的64位Windows2003
2. 通过系统配置来提高ASP.NET应用程序的稳定性(续)
3. 通过系统配置来提高ASP.NET应用程序的稳定性
4. ASP.Net应用程序的多进程模型
5. 编写线程安全的单件(Singleton)
6. .Net 下信号量(Semaphore)的一种实现
随笔分类
(6)
64位操作系统(1)
ASP.NET编程实践(2)
多线程编程技术(3)
随笔档案
(6)
2007年5月 (1)
2006年3月 (2)
2006年2月 (3)
积分与排名
积分 - 15462
排名 - 6307
最新评论
阅读排行榜
评论排行榜
推荐排行榜
编写线程安全的单件(Singleton)
最近在 Review 代码的时候,发现大量类似如下风格的
单件
(Singleton)类:
/**/
///
<summary>
///
线程不安全的 Singleton
///
</summary>
public
class
Singleton
{
static
private
Singleton instance;
private
Singleton()
{
//
//
TODO: Add constructor logic here
//
}
static
public
Singleton Instance
{
get
{
if
( instance
==
null
)
instance
=
new
Singleton();
return
instance;
}
}
}
乍一看还很经典,但细一推敲,却发现了问题:
当
多个线程
同时调用 Singleton.Instance 属性的时候,每个
线程
都检测到 instance == null 为真,于是每个都会傻乎乎的创建一个新实例.这将导致最先创建的实例实效,只有最后创建的实例被保存在静态的 instance 中.虽然这在大多数情况下不会引发大问题,但一旦构造函数中有比较耗时的操作,则会造成程序逻辑上的错误.而这些通常都是隐藏得很深,而且很难复现的超级大Bug .所以,要小心哪,同志们!
为了避免这种问题,我采用了下面的代码:
/**/
///
<summary>
///
线程安全的 Singleton
///
</summary>
public
class
ThreadSafeSingleton
{
static
private
ThreadSafeSingleton instance;
static
private
object
syncObj
=
new
object
();
//
用于线程同步
private
ThreadSafeSingleton()
{
//
//
TODO: Add constructor logic here
//
}
static
public
ThreadSafeSingleton Instance
{
get
{
lock
( syncObj )
//
使用 Monitor 同步
{
if
( instance
==
null
)
instance
=
new
ThreadSafeSingleton();
return
instance;
}
}
}
}
绿色通道:
好文要顶
关注我
收藏该文
与我联系
posted on 2006-02-17 00:06
录一事流
阅读(2437)
评论(10)
编辑
收藏
Feedback
335690
#1楼
2006-02-17 00:47
|
lx[未注册用户]
static ThreadSafeSingleton Instance
{
get
{
if( instance == null )
{
lock( syncObj ) //使用 Monitor 同步
{
if( instance == null )
instance = new ThreadSafeSingleton();
}
}
return instance;
}
}
回复
引用
#2楼
2006-02-17 08:01
|
补丁
又写一遍:
public class ThreadSafeSingleton
{
private ThreadSafeSingleton()
{
}
public static ThreadSafeSingleton Instance = getInstance();
static ThreadSafeSingleton getInstance()
{
return new ThreadSafeSingleton();
}
}
回复
引用
查看
#3楼
2006-02-17 08:36
|
Terrylee
楼主的这种写法也会存在问题
详细请参加我以前写的Sigleton模式的随笔
http://terrylee.cnblogs.com/archive/2005/12/09/293509.html
回复
引用
查看
#4楼
2006-02-17 08:46
|
Nomagic
.NET里实现Singleton用static readonly就好了嘛,不要太理论化了。
回复
引用
查看
#5楼
2006-02-17 09:45
|
windaa[未注册用户]
public class ModuleController
{
private static Dictionary<int, IOAModule> _ModuleList;
public static Dictionary<int, IOAModule> ModuleList
{
get
{
if (_ModuleList == null)
{
lock(_ModuleList)
{
if(_ModuleList==null)
{
_ModuleList = LoadAll();
}
}
}
return _ModuleList;
}
}
}
各位老大看看这个有什么问题吗
回复
引用
#6楼
[
楼主
]
2006-02-17 09:52
|
录一事流
@Terrylee
受教, 文章中的双重锁定方式应是更优的一种实现(避免每次访问都加锁). 谢谢 :)
回复
引用
查看
#7楼
[
楼主
]
2006-02-17 12:16
|
录一事流
@windaa
lock ( _ModuleList ) 这句有问题, 第一次调用时, ModuleList 还是空,而 lock( object ) 语法 等价于 System.Threading.Monitor.Enter( object ), 语句, 这里, object 必须是一个存在的实例.
回复
引用
查看
#8楼
2006-02-17 13:04
|
阿不
类似的代码太多了。
回复
引用
查看
#9楼
2006-02-22 14:50
|
秋枫[未注册用户]
public sealed class Singleton
{
static readonly Singleton instance=new Singleton();
// Explicit static constructor to tell C# compiler
// not to mark type as beforefieldinit
static Singleton()
{
}
Singleton()
{
}
public static Singleton GetInstance()
{
return instance;
}
}
更多
http://blog.csdn.net/zhzuo/archive/2004/07/16/42685.aspx
回复
引用
#10楼
2006-02-22 19:14
|
louisliu
@秋枫
好文! 谢谢!
回复
引用
注册用户登录后才能发表评论,请
登录
或
注册
,
返回博客园首页
。
首页
博问
闪存
新闻
园子
招聘
知识库
最新IT新闻
:
·
最想要的Entity Framework功能
·
专访Jeffrey Richter:Windows 8是微软的重中之重
·
《福布斯》:谷歌进军硬件产品 难撼动苹果地位
·
美国空军拟最多购买1.8万台iPad 2
·
分析称专利之争让谷歌苹果两败俱伤
»
更多新闻...
最新知识库文章
:
·
高级编程语言的发展历程
·
如何学习一门新的编程语言?
·
学习不同编程语言的重要性
·
为什么我喜欢富于表达性的编程语言
·
计算机专业的女生为什么要学编程
»
更多知识库文章...
China-pub 2011秋季教材巡展
China-Pub 计算机绝版图书按需印刷服务