sync.WaitGroup(计数器)
package mainimport ( "fmt" "math/rand" "sync" "time")func randNum(){ rand.Seed(time.Now().UnixNano()) for i := 0; i < 100; i++ { a := rand.Int() b := rand.Intn(10) fmt.Println(a,b) }}var wg sync.WaitGroupfunc main() { for i := 0; i < 10; i++ { wg.Add(1) go func(i int) { defer wg.Done() //如何知道写成社么时间结束 time.Sleep(time.Second*time.Duration(rand.Intn(10))) fmt.Println(i) }(i) } wg.Wait()//等带计数器结束 fmt.Println("22222")}
sync.Mutex(互斥锁)
package mainimport ( "fmt" "sync")func add() { for i := 0; i < 5000; i++ { lock.Lock() v++ lock.Unlock() } wg.Done()}var v int//计时器var wg sync.WaitGroup//互斥锁var lock sync.Mutex//读写锁,读锁可以多个人同时获取,写锁智能一个人获取。当有人获取写锁进行写操作时,读锁和写锁都要进行等待var rwLock sync.RWMutexfunc main() { wg.Add(2) go add() go add() wg.Wait() fmt.Println(v)}
sync.RWMutex(读写锁)
package mainimport ( "fmt" "sync" "time")var v int//计时器var wg sync.WaitGroup//互斥锁var lock sync.Mutex//读写锁,读锁可以多个人同时获取,写锁智能一个人获取。当有人获取写锁进行写操作时,读锁和写锁都要进行等待var rwLock sync.RWMutexfunc write() { rwLock.Lock() fmt.Println(v) v++ rwLock.Unlock() wg.Done()}func read() { rwLock.RLock() fmt.Println(v) rwLock.RUnlock() wg.Done()}func main() { start := time.Now() for i := 0; i < 100; i++ { go write() wg.Add(1) } for i := 0; i < 1000; i++ { go read() wg.Add(1) } wg.Wait() fmt.Println(time.Now().Sub(start))}
sync.Once(高并发下某个操作只做一次)
package mainimport ( "fmt" "sync" "time")var v int//计时器var wg sync.WaitGroup//互斥锁var lock sync.Mutexvar once sync.Oncefunc write() { once.Do(func() { v = 100 }) lock.Lock() v++ lock.Unlock() wg.Done()}func main() { start := time.Now() wg.Add(100) for i := 0; i < 100; i++ { go write() } wg.Wait() //最总v的结果为200 fmt.Println(v) fmt.Println(time.Now().Sub(start))}
sync.Map(并发map包)
package mainimport ( "fmt" "strconv" "sync")var v int//计时器var wg sync.WaitGroup//互斥锁var lock sync.Mutexvar once sync.Once//内置的map不是并发安全的var m1 = sync.Map{}var m2 = make(map[string]string)func main() { wg.Add(100) for i := 0; i < 100; i++ { go func(i int) { key := strconv.Itoa(i) m1.Store(key, key) value, _ := m1.Load(key) fmt.Println(value) wg.Done() }(i) } wg.Wait() wg.Add(100) //普通map最多只支持20个goroutine去并发修改,如果超过20会引发panic,需要加锁解决该问题, //go提供了sync.map来解决此问题 for i := 0; i < 100; i++ { go func(i int) { key := strconv.Itoa(i) m2[key] = key value := m2[key] fmt.Println(value) wg.Done() }(i) } wg.Wait()}