Loading

单例模式

概念

单例模式(Singleton Pattern):单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类称为单例类,它提供全局访问的方法。

要点:

  1. 某个类只有一个实例。
  2. 保证自行创建这个实例。
  3. 向这个系统提供这个实例。

实现分析

基于单例模式的三个要点,代码实现中需要有一下保证:

  • 禁止用户创建实例:私有化构造函数。
  • 单例类提供一个公有方法,该方法负责确保实例存在,并将该实例提供给整个系统使用。

根据实例创建的时间可分为:懒汉模式、饿汉模式。

C++样例

饿汉模式

程序一开始就产生该类的实例。

class Singleton {
public:
    static Singleton* getInstance();

private:
    Singleton();

    static Singleton* INSTANCE;
};

Singleton* Singleton::INSTANCE = new Singleton();

Singleton* Singleton::getInstance() {
    return Singleton::INSTANCE;
}

懒汉模式

程序中第一次使用该类实例时才创建实例。

class Singleton {
public:
    static Singleton* getInstance();

private:
    Singleton();

    static Lock; // 并发锁
    static Singleton* INSTANCE;
};
Singleton* Singleton::INSTANCE = nullptr;

// 线程不安全版本
Singleton* Singleton::getInstance() {
    if (INSTANCE == nullptr) {
        INSTANCE = new Singleton();
    }
    return INSTANCE;
}

// 线程安全版本
Singleton* Singleton::getInstance() {
    if (INSTANCE == nullptr) {
        // Lock 并发锁
        if (INSTANCE == nullptr) {
            INSTANCE = new Singleton();
        }
        // UnLock
    }
    return INSTANCE;
}

Go样例

饿汉模式

func init() {
	// 饿汉模式
	hInstance = &hungerSingleton{}
}
type hungerSingleton struct { }

var hInstance *hungerSingleton

func GetHungerInstance() *hungerSingleton {
	return hInstance
}

懒汉模式

type lazySingleton struct { }

var instance *lazySingleton
var lock sync.Mutex

func GetLazyInstance() *lazySingleton {
	if instance == nil { // 不是完全原子的
		lock.Lock()
		defer lock.Unlock()
		if instance == nil {
			instance = &lazySingleton{}
		}
	}
	return instance
}

// 通过使用sync/atomic这个包,我们可以原子化加载并设置一个标志,以标识是否创建实例
var initialized uint32

func GetLazyInstanceAtom() *lazySingleton {
	if atomic.LoadUint32(&initialized) == 1 {
		return instance
	}

	lock.Lock()
	defer lock.Unlock()
	if instance == nil {
		instance = &lazySingleton{}
		atomic.StoreUint32(&initialized, 1)
	}
	return instance
}

// 通过 sync.Once 来确保创建实例的方法只执行一次
var initOnce sync.Once

func GetLazyInstanceOnce() *lazySingleton {
	initOnce.Do(func() {
		instance = &lazySingleton{}
	})
	return instance
}

参考:

  • 《大话设计模式》 程杰
  • [图说设计模式-单例模式](
posted @ 2021-11-25 19:04  JakeLin  阅读(10)  评论(0编辑  收藏  举报