单例模式,是一种常用的软件设计模式,在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以包在系统中一个类只有一个实例且该实例易于访问,从而方便对实例个数的控制并节约系统资源。

懒汉模式(Lazy Loading)

懒汉模式是开源项目中使用最多的一种,最大的缺点是非线程安全的。

  1. type singleton struct {
  2. }
  3. // private
  4. var instance *singleton
  5. // public
  6. func GetInstance() *singleton {
  7. if instance == nil {
  8. instance = &singleton{} // not thread safe
  9. }
  10. return instance
  11. }

带锁的单例模式

  1. type singleton struct {
  2. }
  3. var instance *singleton
  4. var mu sync.Mutex
  5. func GetInstance() *singleton {
  6. mu.Lock()
  7. defer mu.Unlock()
  8. if instance == nil {
  9. instance = &singleton{} // unnecessary locking if instance already created
  10. }
  11. return instance
  12. }

带检查锁的单例模式

  1. if instance == nil { // <-- Not yet perfect. since it's not fully atomic
  2. mu.Lock()
  3. defer mu.Unlock()
  4. if instance == nil {
  5. instance = &singleton{}
  6. }
  7. }
  8. return instance
  9. }
  10. import "sync"
  11. import "sync/atomic"
  12. var initialized uint32
  13. ...
  14. func GetInstance() *singleton {
  15. if atomic.LoadUInt32(&initialized) == 1 {
  16. return instance
  17. }
  18. mu.Lock()
  19. defer mu.Unlock()
  20. if initialized == 0 {
  21. instance = &singleton{}
  22. atomic.StoreUint32(&initialized, 1)
  23. }
  24. return instance
  25. }

比较好的一种方式sync.Once

  1. import (
  2. "sync"
  3. )
  4. type singleton struct {
  5. }
  6. var instance *singleton
  7. var once sync.Once
  8. func GetInstance() *singleton {
  9. once.Do(func() {
  10. instance = &singleton{}
  11. })
  12. return instance
  13. }

Go 单例模式 - 图1