单例模式(Singleton Pattern)是软件设计中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

非线程安全。当正在创建时,有线程来访问此时LazyInstance = nil就会再创建,单例类就会有多个实例了。

  1. var LazyInstance *Instance
  2. func GetLazyInstance() *Instance {
  3. if LazyInstance == nil {
  4. LazyInstance = &Instance{
  5. Counter: 0,
  6. Name: "LazyInstance",
  7. }
  8. }
  9. return LazyInstance
  10. }

初始化比较耗时间的话,获取的性能比较慢

  1. var HungryInstance = &Instance{Name: "HungryInstance", Counter: 0}
  2. func GetHungryInstance() *Instance {
  3. return HungryInstance
  4. }

每次读取都加锁了,比较好性能,更多的时候获取是不用加锁的

  1. var mu sync.Mutex
  2. var LazyInstancePlus *Instance
  3. func GetLazyInstancePlus() *Instance {
  4. mu.Lock()
  5. defer mu.Unlock()
  6. if LazyInstancePlus == nil {
  7. LazyInstancePlus = &Instance{
  8. Counter: 0,
  9. Name: "LazyInstancePlus",
  10. }
  11. }
  12. return LazyInstancePlus
  13. }

只为空的时候加锁,提高了性能

  1. var LazyInsPlusPlus *Instance
  2. func GetLazyInsPlusPlus() *Instance {
  3. if LazyInsPlusPlus == nil {
  4. mu.Lock()
  5. defer mu.Unlock()
  6. LazyInsPlusPlus = &Instance{
  7. Counter: 0,
  8. Name: "LazyInsPlusPlus",
  9. }
  10. }
  11. return LazyInsPlusPlus
  12. }
  1. var once sync.Once
  2. var SyncOnceInstance *Instance
  3. func GetInstanceSyncOnce() *Instance {
  4. once.Do(func() {
  5. SyncOnceInstance = &Instance{
  6. Counter: 0,
  7. Name: "SyncOnceInstance",
  8. }
  9. })
  10. return SyncOnceInstance
  11. }
  1. package main
  2. import (
  3. "fmt"
  4. "sync"
  5. )
  6. type Instance struct {
  7. Name string
  8. Counter int //详细参数
  9. }
  10. func (i *Instance) Hello() {
  11. fmt.Printf("%s: my current counter is:%d\n", i.Name, i.Counter)
  12. }
  13. //省略实现
  14. func main() {
  15. //懒汉模式测试
  16. ls := GetLazyInstance()
  17. ls.Hello()
  18. ls.Counter += 1
  19. ls1 := GetLazyInstance()
  20. ls1.Hello()
  21. //饿汉模式测试
  22. hs := GetHungryInstance()
  23. hs.Hello()
  24. hs.Counter += 10
  25. hs1 := GetHungryInstance()
  26. hs1.Hello()
  27. //改进型懒汉模式
  28. lsp := GetLazyInstancePlus()
  29. lsp.Hello()
  30. lsp.Counter += 100
  31. lsp1 := GetLazyInstancePlus()
  32. lsp1.Hello()
  33. lspp := GetLazyInsPlusPlus()
  34. lspp.Hello()
  35. lspp.Counter += 1000
  36. lspp1 := GetLazyInsPlusPlus()
  37. lspp1.Hello()
  38. //sync once 测试
  39. sc := GetInstanceSyncOnce()
  40. sc.Hello()
  41. sc.Counter += 10000
  42. sc1 := GetInstanceSyncOnce()
  43. sc1.Hello()
  44. }

结果:

  1. LazyInstance: my current counter is:0
  2. LazyInstance: my current counter is:1
  3. HungryInstance: my current counter is:0
  4. HungryInstance: my current counter is:10
  5. LazyInstancePlus: my current counter is:0
  6. LazyInstancePlus: my current counter is:100
  7. LazyInsPlusPlus: my current counter is:0
  8. LazyInsPlusPlus: my current counter is:1000
  9. SyncOnceInstance: my current counter is:0
  10. SyncOnceInstance: my current counter is:10000

完整代码和测试用例: https://gitee.com/ncuzhangben/GoStudy/tree/master/go-design-pattern/01-Singleton

版权声明:本文为0pandas0原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/0pandas0/p/12036470.html