package main
import (
"fmt"
"sync"
)
var names = []string{"Alan", "Joe", "Jack", "Ben",
"Ellen", "Lisa", "Carl", "Steve", "Anton", "Yo"}
type SyncList struct {
m sync.Mutex
slice []interface{}
}
func NewSyncList(cap int) *SyncList {
return &SyncList{
sync.Mutex{},
make([]interface{}, cap),
}
}
func (l *SyncList) Load(i int) interface{} {
l.m.Lock()
defer l.m.Unlock()
return l.slice[i]
}
func (l *SyncList) Append(val interface{}) {
l.m.Lock()
defer l.m.Unlock()
l.slice = append(l.slice, val)
}
func (l *SyncList) Store(i int, val interface{}) {
l.m.Lock()
defer l.m.Unlock()
l.slice[i] = val
}
func main() {
l := NewSyncList(0)
wg := &sync.WaitGroup{}
wg.Add(10)
for i := 0; i < 10; i++ {
go func(idx int) {
l.Append(names[idx])
wg.Done()
}(i)
}
wg.Wait()
for i := 0; i < 10; i++ {
fmt.Printf("Val: %v stored at idx: %d
", l.Load(i), i)
}
}
/*
Val: Joe stored at idx: 0
Val: Alan stored at idx: 1
Val: Jack stored at idx: 2
Val: Ellen stored at idx: 3
Val: Lisa stored at idx: 4
Val: Ben stored at idx: 5
Val: Carl stored at idx: 6
Val: Steve stored at idx: 7
Val: Anton stored at idx: 8
Val: Yo stored at idx: 9
*/
同步原语Mutex由包同步提供。互斥锁作为锁定在安全部分或资源之上。一旦goroutine里呼吁互斥锁和互斥锁在锁定状态,互斥被锁定和goroutine就进入临界区的互斥访问。如果互斥锁处于锁定状态,锁定的goroutine里调用方法。这个goroutine就堵塞了,需要等到再次得到解锁互斥。
注意,在示例中,我们使用互斥体在片原语上同步访问,这对于并发使用是不安全的。
重要的事实是互斥锁在第一次使用后不能复制。