- 通过go关键字开启协程
func TestGoroutine(t *testing.T){
for i:=0 ; i< 5; i++ {
go (func(i int){
t.Log(i)
})(i)
}
t.Log("hello")
}
使用 go 关键字创建 goroutine 时,被调用函数的返回值会被忽略
- sync.WaitGroup
func TestGoroutine(t *testing.T){
var wg sync.WaitGroup
for i:=0 ; i< 5; i++ {
wg.Add(1)
go (func(i int){
defer wg.Done()
t.Log(i)
})(i)
}
wg.Wait()
t.Log("hello")
}
- 竞态条件
func TestGoroutine(t *testing.T){
for i:=0 ; i< 5; i++ {
go (func(){
t.Log(i)
})()
}
t.Log("hello")
}
go run -race xxx.go
使用race参数可以检测竞态条件
- 加锁 sync.Mutex
func TestGoroutine(t *testing.T){
var lock sync.Mutex
for i:=0 ; i< 5; i++ {
lock.Lock()
go (func(){
defer lock.Unlock()
t.Log(i)
})()
}
t.Log("hello")
}
在读多写少的环境中,可以优先使用读写互斥锁(sync.RWMutex),它比互斥锁更加高效。sync 包中的 RWMutex 提供了读写互斥锁的封装
- atomic
- 调整并发性能
runtime.GOMAXPROCS(runtime.NumCPU())
thead vs groutine
- java thead stack 默认是1M
- groutine stack 初始化为 2k
groutime vs coroutine
- goroutine 可能发生并行执行
- 但 coroutine 始终顺序执行
- groutime与coroutine区别