package main import ( "fmt" "sync" "time" ) var wg = sync.WaitGroup{} var rwm = sync.RWMutex{} func read() { rwm.RLock() // 加读锁 fmt.Println("读取数据开始") time.Sleep(time.Second) fmt.Println("读取数据结束") rwm.RUnlock() // 解除读锁 wg.Done() } func write() { rwm.Lock() // 加写锁 fmt.Println("写入数据开始") time.Sleep(time.Second * 5) fmt.Println("写入数据结束") rwm.Unlock() // 解除写锁 wg.Done() } func main() { for i := 0; i < 5; i++ { wg.Add(1) go read() } wg.Add(1) go write() wg.Wait() } //========== 输出过程·开始 ==========// // 读取数据开始 // 读取数据结束 // 写入数据开始 // 写入数据结束 // 读取数据开始 // 读取数据开始 // 读取数据开始 // 读取数据开始 // 读取数据结束 // 读取数据结束 // 读取数据结束 // 读取数据结束 //========== 输出过程·结束 ==========// //========== 总结 ==========// // 1、sync.RWMutex和sync.Mutex其实差不多,只是sync.RWMutex允许并发读所以更高效,比较适合读多写少的场景。 // 2、处理并发问题应该始终优先考虑使用管道(channel),管道在Go语言里的地位非常高,除非是遇到了连管道也无法解决的问题, // 否则都应该使用管道。
Copyright © 2024 码农人生. All Rights Reserved