@aliasliyu4
2016-09-01T10:38:28.000000Z
字数 826
阅读 3547
单例常用在固定资源的调用上,比如配置文件的加载之后,代码各处都可以使用。
package mainimport ("fmt""sync""time")//单例定义type Single struct {Sone *OneStwo *Two}type One struct {One string}type Two struct {Two string}//定义锁var (singleton *Singlelock sync.Mutex)func NewSingle() *Single {//这里假设有两个goroutine,一个在第一个条件,一个在第二个条件//这就避免了加start函数执行两次的问题,也就是是一个实在的单例//尽量不要用defer,因为这虽然是方便,但是会带来不必要的开销if singleton == nil {lock.Lock()if singleton == nil {fmt.Println("shoule enter only!")singleton = start()}lock.Unlock()}return singleton}func start() *Single {one := one()two := two()single := &Single{Sone: one,Stwo: two,}return single}func one() *One {one := &One{One: "one",}return one}func two() *Two {two := &Two{Two: "two",}return two}func main() {//1000个goroutine执行单例,可以看到的结果是单例只初始化了一次for i := 0; i < 1000; i++ {go func() {single := NewSingle()fmt.Println(single)}()}//防止main.goroutine退出,导致其他goroutine不能被执行time.Sleep(time.Second * 6)}