单例模式(Singleton Pattern)
2015-08-26 00:06
288 查看
单例模式(Singleton Pattern)
确保一个类只有一个实例,并提供一个全局访问点。
1、经典实现
1)利用一个静态变量来记录Singleton类的唯一实例;
2)将构造器声明为私有的;
3)使用GetInstance()方法实例化对象,并返回该实例(全局访问点)。
class Singleton
{
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton GetInstance()
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
#if LANGUAGE_CPP
class Singleton
{
public:
static Singleton *GetInstance();
protected:
Singleton();
private:
static Singleton *uniqueInstance;
}
Singleton *Singleton::uniqueInstance = null;
Singleton *Singleton::GetInstance()
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
#endif2、处理多线程
1)将GetInstance()方法变成同步(synchronized)的方法。为了同步,该处理方式会影响程序性能;
2)用“双重检测加锁”(double-checked locking),在GetInstance()方法中减少同步使用;
3)使用“急切”(eager)方式创建实例,而不用延迟实例化的做法。
C#中使用“静态初始化”方式,将实例变量标记为readonly,意味着只能在静态初始化期间或在类的构造器中分配变量。这种静态初始化的方式是在自己被加载时就将自己实例化,所以被称为饿汉式单例类;前面的实现方式是在第一次被应用时,才将自己实例化,所以被称为懒汉式单例。
class SingletonMT
{
private static SingletonMT uniqueInstance;
private static readonly object syncRoot = new object();
private SingletonMT() { }
public static SingletonMT GetInstance()
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
uniqueInstance = new SingletonMT();
}
}
return uniqueInstance;
}
}
// double-checked locking
class SingletonDL
{
private static SingletonDL uniqueInstance;
private static readonly object syncRoot = new object();
private SingletonDL() { }
public static SingletonDL GetInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
uniqueInstance = new SingletonDL();
}
}
}
return uniqueInstance;
}
}
class Singleton
{
private static readonly Singleton uniqueInstance = new Singleton();
private Singleton() { }
public static Singleton GetInstance()
{
return uniqueInstance;
}
}
#if LANGUAGE_JAVA
class SingletonMT
{
private static SingletonMT uniqueInstance;
private SingletonMT() {}
public static synchronized SingletonMT GetInstance() {
if (uniqueInstance == null) {
uniqueInstance = new SingletonMT();
}
return uniqueInstance;
}
}
class SingletonDL
{
private static SingletonDL uniqueInstance;
private SingletonDL() {}
public static SingletonDL GetInstance() {
if (uniqueInstance == null) {
synchronized (SingletonDL.class) {
if (uniqueInstance == null) {
uniqueInstance = new SingletonDL();
}
}
}
return uniqueInstance;
}
}
class Singleton
{
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton GetInstance() {
return uniqueInstance;
}
}
#endif3、注意与全局变量、静态变量的区别
确保一个类只有一个实例,并提供一个全局访问点。
1、经典实现
1)利用一个静态变量来记录Singleton类的唯一实例;
2)将构造器声明为私有的;
3)使用GetInstance()方法实例化对象,并返回该实例(全局访问点)。
class Singleton
{
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton GetInstance()
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
#if LANGUAGE_CPP
class Singleton
{
public:
static Singleton *GetInstance();
protected:
Singleton();
private:
static Singleton *uniqueInstance;
}
Singleton *Singleton::uniqueInstance = null;
Singleton *Singleton::GetInstance()
{
if (uniqueInstance == null)
{
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
#endif2、处理多线程
1)将GetInstance()方法变成同步(synchronized)的方法。为了同步,该处理方式会影响程序性能;
2)用“双重检测加锁”(double-checked locking),在GetInstance()方法中减少同步使用;
3)使用“急切”(eager)方式创建实例,而不用延迟实例化的做法。
C#中使用“静态初始化”方式,将实例变量标记为readonly,意味着只能在静态初始化期间或在类的构造器中分配变量。这种静态初始化的方式是在自己被加载时就将自己实例化,所以被称为饿汉式单例类;前面的实现方式是在第一次被应用时,才将自己实例化,所以被称为懒汉式单例。
class SingletonMT
{
private static SingletonMT uniqueInstance;
private static readonly object syncRoot = new object();
private SingletonMT() { }
public static SingletonMT GetInstance()
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
uniqueInstance = new SingletonMT();
}
}
return uniqueInstance;
}
}
// double-checked locking
class SingletonDL
{
private static SingletonDL uniqueInstance;
private static readonly object syncRoot = new object();
private SingletonDL() { }
public static SingletonDL GetInstance()
{
if (uniqueInstance == null)
{
lock (syncRoot)
{
if (uniqueInstance == null)
{
uniqueInstance = new SingletonDL();
}
}
}
return uniqueInstance;
}
}
class Singleton
{
private static readonly Singleton uniqueInstance = new Singleton();
private Singleton() { }
public static Singleton GetInstance()
{
return uniqueInstance;
}
}
#if LANGUAGE_JAVA
class SingletonMT
{
private static SingletonMT uniqueInstance;
private SingletonMT() {}
public static synchronized SingletonMT GetInstance() {
if (uniqueInstance == null) {
uniqueInstance = new SingletonMT();
}
return uniqueInstance;
}
}
class SingletonDL
{
private static SingletonDL uniqueInstance;
private SingletonDL() {}
public static SingletonDL GetInstance() {
if (uniqueInstance == null) {
synchronized (SingletonDL.class) {
if (uniqueInstance == null) {
uniqueInstance = new SingletonDL();
}
}
}
return uniqueInstance;
}
}
class Singleton
{
private static Singleton uniqueInstance = new Singleton();
private Singleton() {}
public static Singleton GetInstance() {
return uniqueInstance;
}
}
#endif3、注意与全局变量、静态变量的区别
相关文章推荐
- C语言编写控制台下PE分析工具(二)
- 题目:主元素 III
- 如何在C++中调用C程序?
- zstuoj 4186 表白计划(区间操作x线段树)
- CompletePack - 完全背包模板
- 自动测试平台---ATE.NET
- 如何将一列数据变为5列一换行的形式
- spring 单元测试
- 2015-8-25股市大跌
- 数论 + 公式 - HDU 4335 What is N?
- 简介二分查找算法与相关的Python实现示例
- php面向对象与面向过程两种方法给图片添加文字水印
- php基础教程
- 数据库访问性能优化
- sql server 性能优化之nolock
- javascript中alert()与console.log()的区别
- js钢琴按钮波浪式图片排列效果代码分享
- jquery用ajax方式从后台获取json数据后如何将内容填充到下拉列表
- jQuery三级下拉列表导航菜单代码分享
- jquery实现的横向二级导航效果代码