如何用Go语言高效实现并遵循安全双检锁的最佳实践?
- 内容介绍
- 文章标签
- 相关推荐
本文共计4224个文字,预计阅读时间需要17分钟。
从其他语言转换为Go语言的同学生常会遇到一个思考:如何创建一个实例?有些同学可能会将其他语言中的双重检查模式移植过来,双重检查模式也称懒汉式,首次使用时才创建实例。
从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实例。但是Go没有Java中的volatile修饰符,它怎么保证线程安全呢? 不安全的双检锁从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?
有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实例。大部分人首次用Golang写出来的实例大概是这样的:
type Conn struct {
Addr string
State int
}
var c *Conn
var mu sync.Mutex
func GetInstance() *Conn {
if c == nil {
mu.Lock()
defer mu.Unlock()
if c == nil {
c = &Conn{"127.0.0.1:8080", 1}
}
}
return c
}
这里先解释下这段代码的执行逻辑(已经清楚的同学可以直接跳过):
GetInstance用于获取结构体Conn的一个实例,其中:先判断c是否为空,如果为空则加锁,加锁之后再判断一次c是否为空,如果还为空,则创建Conn的一个实例,并赋值给c。
本文共计4224个文字,预计阅读时间需要17分钟。
从其他语言转换为Go语言的同学生常会遇到一个思考:如何创建一个实例?有些同学可能会将其他语言中的双重检查模式移植过来,双重检查模式也称懒汉式,首次使用时才创建实例。
从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实例。但是Go没有Java中的volatile修饰符,它怎么保证线程安全呢? 不安全的双检锁从其他语言转入Go语言的同学经常会陷入一个思考:如何创建一个单例?
有些同学可能会把其它语言中的双检锁模式移植过来,双检锁模式也称为懒汉模式,首次用到的时候才创建实例。大部分人首次用Golang写出来的实例大概是这样的:
type Conn struct {
Addr string
State int
}
var c *Conn
var mu sync.Mutex
func GetInstance() *Conn {
if c == nil {
mu.Lock()
defer mu.Unlock()
if c == nil {
c = &Conn{"127.0.0.1:8080", 1}
}
}
return c
}
这里先解释下这段代码的执行逻辑(已经清楚的同学可以直接跳过):
GetInstance用于获取结构体Conn的一个实例,其中:先判断c是否为空,如果为空则加锁,加锁之后再判断一次c是否为空,如果还为空,则创建Conn的一个实例,并赋值给c。

