转 -- Singleton模式
来源:互联网 发布:windows怎么切换mac 编辑:程序博客网 时间:2024/04/28 16:49
这两天需要看看设计模式中的几个常用模式,于是就边看边记录了。
先来一个基本的,原址如下:
http://developer.51cto.com/art/200907/135303.htm
最简单的设计模式学习:Singleton模式
本文介绍了学习设计模式中最简单的模式:Singleton模式。Singleton的用处自然是保证一个类只有一个唯一的实例。
学习设计模式,自然从最简单的模式入手,而最简单的模式便是Singleton。所以第一篇就来所以说Singleton模式。看完GOF和Design patterns in Java的书,感觉Singleton虽然简单,但是想写出一个好的Singleton也不是一上来就能写出来的。
Singleton模式的用处自然是保证一个类只有一个唯一的实例。在建模中涉及到的只能有一个对象,例如Struts中的Action类就是一例。除此之外,Singleton还使得该对象只有一个全局访问点。这就是SIngleton的作用。
说得比较抽象,我们来看一个简单Singleton的C++和Java的代码:
C++ Singleton模式:
类定义:
- class Singleton
- {
- public:
- static Singleton * Instance();
- ~Singleton();
- private:
- Singleton();
- static Singleton * instance;
- };
方法实现:
- Singleton * Singleton::instance = 0;
- Singleton::Singleton()
- {
- }
- Singleton::~Singleton()
- {
- }
- Singleton * Singleton::Instance()
- {
- if (instance == 0) {
- instance = new Singleton();
- }
- return instance;
- }
Java Singleton模式:
- public class Singleton {
- private static Singleton instance;
- public static Singleton getInstance() {
- if (instance == null)
- instance = new Singleton();
- return instance;
- }
- /** *//** Creates a new instance of Singleton */
- private Singleton() {
- }
- }
通过上面的例子可以看出,Singleton的实现并不难,只要将构造函数访问域设为私有,然后添加一个静态引用和一个获得该应用的静态方法即可。其实在C++中定义一个全局静态变量也可以达到这个效果,但是像Java这样的语言就是能使用Singleton了。
上面的程序有一个问题,就是只能运行在单线程的环境下。为此我在C++上作了个实验。首先#include 。在SIngleton::Instance()函数中增加一个Sleep(1000),程序如下:
- Singleton * Singleton::Instance()
- {
- if (instance == 0) {
- Sleep(1000);
- instance = new Singleton();
- }
- return instance;
- }
然后在主函数中创建两个线程,程序如下:
- static Singleton * s1 = 0, * s2 = 0;
- DWORD WINAPI ThreadProc1(PVOID)
- {
- s1 = Singleton::Instance();
- return 0;
- }
- DWORD WINAPI ThreadProc2(PVOID)
- {
- s2 = Singleton::Instance();
- return 0;
- }
- int main(int argc, char* argv[])
- {
- DWORD threadID1;
- DWORD threadID2;
- CreateThread(NULL, 0, ThreadProc1, NULL, 0, &threadID1);
- CreateThread(NULL, 0, ThreadProc2, NULL, 0, &threadID2);
- Sleep(10000);
- std::cout << s1 << " " << s2;
- return 0;
- }
这样修改后在运行程序,打印出来的s1和s2地址就不是同一个地址了。结果如下:
0372D68 00372E68Press any key to continue
可见当在多线程环境下使用这个Singleton就会出现创建不止一个实力的情况,所以我们需要给Singleton加锁。请看下面的代码。
C++ Singleton模式:
- class Singleton
- {
- public:
- static Singleton * Instance();
- virtual ~Singleton();
- private:
- Singleton();
- static CMutex mutex;
- static Singleton * instance;
- };
- Singleton * Singleton::instance = 0;
- CMutex Singleton::mutex;
- Singleton::Singleton()
- {
- }
- Singleton::~Singleton()
- {
- }
- Singleton * Singleton::Instance()
- {
- mutex.Lock();
- if (instance == 0) {
- Sleep(1000);
- instance = new Singleton();
- }
- mutex.Unlock();
- return instance;
- }
此外需要#include < afxmt.h>,,并且在项目设置中要设置动态链接MFC库。
Java Singleton模式:
- public class Singleton {
- private static Singleton instance;
- private static Object lock = Singleton.class;
- public static Singleton getInstance() {
- synchronized (lock) {
- if (instance == null)
- instance = new Singleton();
- return instance;
- }
- }
- /** *//** Creates a new instance of Singleton */
- private Singleton() {
- }
- }
运用加锁就可以解决在多线程环境下使用Singleton模式所带来的问题了。
- 转 -- Singleton模式
- Singleton模式
- Singleton模式
- singleton模式
- Singleton模式
- Singleton模式
- Singleton模式
- Singleton模式
- Singleton 模式
- Singleton模式
- Singleton模式
- singleton模式
- Singleton模式
- Singleton 模式
- Singleton 模式
- Singleton 模式
- Singleton模式
- Singleton模式
- 真要配带眼镜吗?
- 创新工场的失败&我们应学到的经验——李开复
- gem ERROR: While executing gem ... (Zlib::GzipFile::Error)
- POJ 3070 Fibonacci 矩阵快速幂
- Java应用——精简jre体积
- 转 -- Singleton模式
- 2012年总结
- android图像绘制(一)——镜像问题
- Android学习笔记之ProgressDialog
- 01背包源码核心算法
- 使用maven创建appfuse
- 144D Missile Silos (data structures, graphs, shortest paths)
- HDU 4022 Bombing STL/二分
- 命令执行顺序