-------------
sync.Once.Do(f func())是一个挺有趣的东西,能保证once只执行一次,无论你是否更换once.Do(xx)这里的方法,这个sync.Once块只会执行一次。
package main import ( "fmt" "sync" "time" ) var once sync.Once func main() { for i, v := range make([]string, 10) { once.Do(onces) fmt.Println("count:", v, "---", i) } for i := 0; i < 10; i++ { go func() { once.Do(onced) fmt.Println("213") }() } time.Sleep(time.Second*1) } func onces() { fmt.Println("onces") } func onced() { fmt.Println("onced") }
整个程序,只会执行onces()方法一次,onced()方法是不会被执行的
package main import ( "fmt" "sync" "time" ) var once sync.Once func main() { for i, v := range make([]string, 10) { once.Do(onces) fmt.Println("count:", v, "---", i) } for i := 0; i < 10; i++ { go func(i int) { once.Do(onced) fmt.Println("213", "---", i) }(i) } time.Sleep(time.Second * 1) } func onces() { fmt.Println("onces") } func onced() { fmt.Println("onced") }
--------------
package singleton import ( "unsafe" "fmt" "sync" "testing" ) //协程安全 单例模式 type Singleton struct { } var singleintance *Singleton var once sync.Once //只执行一次 func GetSingletonObj() *Singleton { once.Do(func() { fmt.Println("Create Obj") singleintance = new(Singleton) }) return singleintance } func TestGetSingletonObj(t *testing.T) { var wg sync.WaitGroup //协程安全 for i := 0; i < 10; i++ { wg.Add(1) go func() { obj := GetSingletonObj() fmt.Printf("%x\n",unsafe.Pointer(obj))//输出的结果都是同一个地址 wg.Done() }() } wg.Wait() //等待是有协程运行完成 }