1、竟态问题
func TestG1(t *testing.T) {
count := 1
for i := 0; i < 1000; i++ {
go func() {
count++
}()
}
fmt.Println(count)
count2 := 0
lock := &sync.Mutex{}
wg := &sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
lock.Lock()
defer lock.Unlock()
count2++
}()
}
wg.Wait()
fmt.Println(count2)
count3 := atomic.Int64{}
wg := &sync.WaitGroup{}
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
count3.Add(1)
}()
}
wg.Wait()
fmt.Println(count3.Load())
}
2、闭包问题
func TestG2(t *testing.T) {
wg := sync.WaitGroup{}
onlyOne := 0
for i := 0; i < 10; i++ {
wg.Add(1)
onlyOne = i
go func() {
defer wg.Done()
fmt.Println(onlyOne)
}()
}
wg.Wait()
wg2 := sync.WaitGroup{}
for i := 0; i < 3; i++ {
wg2.Add(1)
go func() {
defer wg2.Done()
fmt.Println(i)
}()
}
wg2.Wait()
fmt.Println("--------------")
wg3 := sync.WaitGroup{}
for i := 0; i < 3; i++ {
wg3.Add(1)
go func(j int) {
defer wg3.Done()
fmt.Println(j)
}(i)
}
wg3.Wait()
fmt.Println("--------------")
onlyOne4 := 0
fmt.Println(fmt.Printf("onlyOne4 %p\n", &onlyOne4))
wg4 := sync.WaitGroup{}
for i := 0; i < 3; i++ {
wg4.Add(1)
onlyOne4 = i
go func(onlyOne4 int) {
defer wg4.Done()
fmt.Println(fmt.Printf("onlyOne4 %p\n", &onlyOne4))
fmt.Println(onlyOne4)
}(onlyOne4)
}
wg4.Wait()
}
三、死锁
func TestG3(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(11)
for i := 0; i < 10; i++ {
go func() {
defer wg.Done()
fmt.Println(time.Now())
}()
}
wg.Wait()
}
func TestG32(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
receiveWG(wg)
wg.Wait()
}
func receiveWG(wg sync.WaitGroup) {
wg.Done()
}
func TestG33(t *testing.T) {
wg := sync.WaitGroup{}
wg.Add(1)
receiveWG33(&wg)
wg.Wait()
}
func receiveWG33(wg *sync.WaitGroup) {
wg.Done()
}
四、携程泄露 (注意关闭资源)
func TestG4(t *testing.T) {
go func() {
ch := make(chan int)
<-ch
}()
fmt.Println(runtime.NumGoroutine())
}