变量安全
当多个协程读写同一个变量时,很可能会造成冲突。
- 常见的解决办法就是加锁(可见sync.Mutex),如下所示。当这中写法就比较繁琐,一个变量配一把锁,当然也可以多个变量配一把锁,这样会导致冲突增多,影响性能
- 另一种解决办法是golang提供的atomic包,包中的函数都是原子操作,也就是安全的,写法也更简单
var count int64
//加锁
var mutex sync.Mutex
mutex.Lock()
count += 1
mutex.Unlock()
//atomic
atomic.AddInt64(&count,1) //count = count + 1
map
type SafeMap struct {
data map[interface{}]interface{}
ch chan func()
}
var inst *SafeMap
func NewSafeMap() *SafeMap {
if inst == nil {
s := &SafeMap{
data: make(map[interface{}]interface{}),
ch: make(chan func()),
}
go func() {
for {
(<-s.ch)()
}
}()
inst = s
return inst
}
return inst
}
func (s *SafeMap) Add(key interface{}, value interface{}) {
s.ch <- func() {
s.data[key] = value
}
}
select
- 当没有case发生时,若存在default则会执行default;若不存在default则会阻塞
- 当有多个case发生时,会随机选择一个case执行
自定义case优先级的方法:在低优先级的case中判断高优先级的case是否发生
select {
case <- ch1 :
fmt.Println("chan 1")
case <- ch2 :
if len(ch1) != 0 {
fmt.Println("chan 1")
break
}
fmt.Println("chan 2")
}