GO 單例模式

單例模式是經常使用的模式之一,通常介紹的單例模式有 餓漢式懶漢式 等,無論那種模式最終目的只有一個,就是隻實例化一次,僅容許一個實例存在。git

GO語言實現單例模式相對簡單,這裏考慮到併發,用到了sync.Mutex 和結構體sync.Once。github

示例:golang

package main

import (
   "fmt"
   "sync"
)

var (
   lock     *sync.Mutex = &sync.Mutex{}
   instance *Singleton
)
type Singleton struct {
}

func GetInstance() *Singleton {
   if instance == nil {
      lock.Lock()
      defer lock.Unlock()
      if instance == nil {
         instance = &Singleton{}
         fmt.Println("instance...")
      }
   }
   return instance
}

func main() {
   var s *Singleton
   s = GetInstance()
   s = GetInstance()
   fmt.Println(s)
}

執行結果:併發

instance...
&{}函數

經過結果能夠看到只輸出了一個instance...。atom

上面的實現方式還能夠經過結構體sync.Once更優雅的實現。code

示例:get

package main

import (
   "fmt"
   "sync"
)

var (
   once sync.Once
   instance *Singleton
)

type Singleton struct {
}

func GetInstance() *Singleton {
    once.Do(func() {
        instance = &Singleton{}
        fmt.Println("instance...")
    })
   return instance
}

func main() {
   var s *Singleton
   s = GetInstance()
   s = GetInstance()
   fmt.Println(s)
}

輸出結果:it

instance...
&{}ast

經過sync.Once的源代碼查看它是如何運行的

func (o *Once) Do(f func()) {
   if atomic.LoadUint32(&o.done) == 1 {
      return
   }
   // Slow-path.
   o.m.Lock()
   defer o.m.Unlock()
   if o.done == 0 {
      defer atomic.StoreUint32(&o.done, 1)
      f()
   }
}

sync.Once.Do(f func())使用加鎖原子操做(代碼包sync/atomic)來保證函數 f 只執行一次。

相關文章
相關標籤/搜索