本文共 1678 字,大约阅读时间需要 5 分钟。
目录
单例模式是最简单的设计模式之一,它提供了创建对象的最佳方式。这种模式涉及到一个单一的结构体,该结构体负责创建自己的对象,同时确保只有单个对象被创建。即多次创建一个结构体的对象,得到的对象的存储地址永远与第一次创建对象的存储地址相同。
利用 sync.Once 方法Do,确保Do中的方法只被执行一次的特性,创建单个结构体实例。
import ( "sync")var ( instance *School once sync.Once)type School struct { Name string Tel string}func CreateSchool(name, tel string) *School { once.Do(func() { instance = new(School) instance.Name = name instance.Tel = tel }) return instance}
使用Do方法也巧妙的保证了并发线程安全。
package mainimport ( "fmt" "strconv" "sync")var ( instance *School once sync.Once)type School struct { Name string Tel string}func CreateSchool(name, tel string) *School { once.Do(func() { fmt.Println("----- init -----") instance = new(School) instance.Name = name instance.Tel = tel }) return instance}func main() { var wg sync.WaitGroup wg.Add(10) for i:=0; i<10; i++ { go func(seq int) { defer wg.Done() seqStr := strconv.Itoa(seq) school := CreateSchool("school"+seqStr, seqStr) fmt.Printf( "%s\tname: %s,\t tel: %s,address:%p\n", seqStr, school.Name, school.Tel, school, ) } (i) } wg.Wait()}
执行结果:
----- init -----9 name: school9, tel: 9,address:0xc0000b00002 name: school9, tel: 9,address:0xc0000b00005 name: school9, tel: 9,address:0xc0000b00003 name: school9, tel: 9,address:0xc0000b00004 name: school9, tel: 9,address:0xc0000b00006 name: school9, tel: 9,address:0xc0000b00000 name: school9, tel: 9,address:0xc0000b00008 name: school9, tel: 9,address:0xc0000b00007 name: school9, tel: 9,address:0xc0000b00001 name: school9, tel: 9,address:0xc0000b0000
可以看出,Do函数中的内容仅被执行了一次,所有实例化的对象都有相同的内容,且指向的地址相同。
转载地址:http://xdsoi.baihongyu.com/