单例模式它确保一个类只有一个实例,并提供一个全局的访问点以访问该实例,简单来说就是我有一个实例,你只能通过我提供的方式来去初始化或得到它。根据它的定义我们可是将其应用到数据库连接对象等的设计。
单例分为饿汉式和懒汉式
//初始化一个结构体,只能通过这个方法去拿到初始化后的实例
package main
type singleton struct {
}
var instance = &singleton{}
func GetSingleTon() *singleton {
return instance
}
上面的代码在加载main包是就初始化好了singleton结构体,但你要通过我提供的方法去拿到这个实例。
type singleton struct {
}
var instance *singleton
func GetSingleTon() *singleton {
if instance != nil {
instance = &singleton{}
}
return instance
}
在我需要获取实例的时候再进行初始化,能降低一些性能消耗。
大家学过Go都了解Go语言是天生高并发的语言,那肯定要考虑在高并发下的应用问题,上面的懒汉式在并发中会出问题,那要如何解决呢?
多并发处理数据同步的方式最常见的就是加锁的操作,在这里我们加上一个读写锁,问题就迎刃而解了。
type singleton struct {
}
var instance *singleton
var mu sync.Mutex
func GetSingleTon() *singleton {
mu.Lock()
//在方法返回前解锁
defer mu.Unlock()
if instance != nil {
instance = &singleton{}
}
return instance
}
这样反复的加锁必然会带来一些性能上的消耗,但这些消耗可能说是必要的。