第9章 基于共享变量的并发
前一章我们使用了goroutine和channel这样直接而自然的方式来实现并发的方法,有时候它们会存在一些问题
本章我们会更详细的介绍并发机制,尤其在goroutine之间共享变量,我们还会介绍goroutine和操作系统线程之间一些技术差别
9.5 sync.Once惰性初始化
一般情况下,在程序的刚开始就对变量进行初始化其实成本比较大,这会增加启动时间,但如果在使用的时候再去初始化变量,这会是一个比较好的方式,我们来看一下早些时候的一个变量
var icons map[string]image.Image
func loadIcons(){
icons = map[string]image.Image{
"spades.png": loadIcons("spades.png"),
"hearts.png": loadIcons("hearts.png"),
"diamonds.png": loadIcons("iamonds.png"),
"clubs.png": loadIcons("clubs.png"),
}
}
func Icon(name string)image.Image {
if icons == nil{
loadIcons()
}
return icons[name]
}
如果只有一个单独的goroutine的话,我们可以使用上述模板,但是这种模版在Icon被并发调用时并不安全,这个道理和前面的Deposit函数一样的,直觉会告诉我们这将导致数据竞争,也就是说可能存在多个goroutine进去Icon函数,发现变量是nil&#