GOシングルモード
単例モードはよく用いられるモードの1つであり、一般に紹介される単例モードは
GO言語は単一例のモードを実現するのは比較的簡単で、ここでは同時を考慮してsyncを用いた.Mutexと構造体sync.Once.
例:
実行結果:
instance...&{}
結果としてinstanceが1つしか出力されていないことがわかります....
以上の実施形態は、構造体syncによってもよい.Onceのより優雅な実現.
例:
出力結果:
instance...&{}
syncを通ります.Onceのソースコードはどのように実行されているかを表示します
sync.Once.Do(f func()は、関数fが一度だけ実行されることを保証するために、ロック原子操作(コードパケットsync/atomic)を使用する.ディレクトリ
や
などであり、そのモードの最終目的が1つであっても、一度だけインスタンス化され、1つのインスタンスのみが存在することを許容する.GO言語は単一例のモードを実現するのは比較的簡単で、ここでは同時を考慮してsyncを用いた.Mutexと構造体sync.Once.
例:
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が1つしか出力されていないことがわかります....
以上の実施形態は、構造体syncによってもよい.Onceのより優雅な実現.
例:
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)
}
出力結果:
instance...&{}
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()は、関数fが一度だけ実行されることを保証するために、ロック原子操作(コードパケットsync/atomic)を使用する.