Go Singleton 单例模式

第一个版本:单线程下是线程安全:

package main    
import "fmt"    
var instance *Singleton    
type Singleton struct {
	Name string
}    
// 非线程安全版本Singleton
func GetInstance() *Singleton{
    	if instance == nil{
		instance = &Singleton{}
		return instance
	}
	return instance
}   

func main(){   
s1 := GetInstance()
fmt.Printf("s1 指针是%p \n",s1)

s2 := GetInstance()
fmt.Printf("s2 指针是%p \n",s2)

}

从结果中可以看出单线程下是安全

s1 指针是0xc00004e1c0
s2 指针是0xc00004e1c0

第二个版本 多线程 :

package main

import (
	"fmt"
	"time"
)

var instance *Singleton

type Singleton struct {
	Name string
}

// 非线程安全版本Singleton
func GetInstance() *Singleton{

	if instance == nil{
		fmt.Println("---------------")
		instance = &Singleton{}
		return instance
	}
	return instance
}


func main(){
	for i := 0 ;i <5 ;i ++ {
		go func(i int) {
			s := GetInstance()
			fmt.Printf("i= %d, s = %p\n", i, s)
		}(i)

	}
time.Sleep(time.Second)

}

从运行的结果中可以看出, 在多线程下不安全的

---------------
---------------
i= 1, s = 0xc0000c6000
---------------
i= 4, s = 0xc0000c6020
i= 0, s = 0xc000040010
---------------
i= 3, s = 0xc00004e1c0
---------------
i= 2, s = 0xc00004e1e0

第三个版本,使用mutex锁机制:

package main

import (
	"fmt"
	"sync"
	"time"
)

var instance *Singleton
var mu sync.Mutex
type Singleton struct {
	Name string
}

// 非线程安全版本Singleton
func GetInstance() *Singleton{
	mu.Lock()
	defer mu.Unlock()
	if instance == nil{
		fmt.Println("---------------")
		instance = &Singleton{}
		return instance
	}
	return instance
}


func main(){
	for i := 0 ;i <5 ;i ++ {
		go func(i int) {
			s := GetInstance()
			fmt.Printf("i= %d, s = %p\n", i, s)
		}(i)

	}
time.Sleep(time.Second)
    }

从运行的结果中可以看出, 在多线程下运行是线程安全的,但是由于锁的机制,运行的效率不高。

---------------
i= 2, s = 0xc000040010
i= 4, s = 0xc000040010
i= 0, s = 0xc000040010
i= 1, s = 0xc000040010
i= 3, s = 0xc000040010

第四个版本 使用 sync.Once 初始化

package main

import (
	"fmt"
	"sync"
	"time"
)

var instance *Singleton
var once sync.Once
type Singleton struct {
	Name string
}

// 线程安全版本Singleton
func GetInstance() *Singleton{
	once.Do(
		func() {
			if instance == nil{
				fmt.Println("---------------")
				instance = &Singleton{}
			}
		})
	return instance
}



func main(){
	for i := 0 ;i <5 ;i ++ {
		go func(i int) {
			s := GetInstance()
			fmt.Printf("i= %d, s = %p\n", i, s)
		}(i)
	}
time.Sleep(time.Second)
}

从运行的结果看,是一个线程安全

i= 0, s = 0xc000040010
i= 1, s = 0xc000040010
i= 3, s = 0xc000040010
i= 4, s = 0xc000040010
i= 2, s = 0xc000040010
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值