1 读写互斥锁

互斥锁是完全互斥的,但是有很多实际的场景下是读多写少的,当我们并发的去读取一个资源不涉及资源修改的时候是没有必要加锁的,这种场景下使用读写锁是更好的一种选择。
读写锁分为两种:读锁和写锁。
当一个goroutine获取读锁之后,其他的goroutine如果是获取读锁会继续获得锁,如果是获取写锁就会等待;
当一个goroutine获取写锁之后,其他的goroutine无论是获取读锁还是写锁都会等待。

  1. var (
  2. x int64
  3. wg sync.WaitGroup
  4. lock sync.Mutex
  5. rwlock sync.RWMutex
  6. )
  7. func write() {
  8. // lock.Lock() // 加互斥锁
  9. rwlock.Lock() // 加写锁
  10. x = x + 1
  11. time.Sleep(10 * time.Millisecond) // 假设读操作耗时10毫秒
  12. rwlock.Unlock() // 解写锁
  13. // lock.Unlock() // 解互斥锁
  14. wg.Done()
  15. }
  16. func read() {
  17. // lock.Lock() // 加互斥锁
  18. rwlock.RLock() // 加读锁
  19. time.Sleep(time.Millisecond) // 假设读操作耗时1毫秒
  20. rwlock.RUnlock() // 解读锁
  21. // lock.Unlock() // 解互斥锁
  22. wg.Done()
  23. }
  24. func main() {
  25. start := time.Now()
  26. for i := 0; i < 10; i++ {
  27. wg.Add(1)
  28. go write()
  29. }
  30. for i := 0; i < 1000; i++ {
  31. wg.Add(1)
  32. go read()
  33. }
  34. wg.Wait()
  35. end := time.Now()
  36. fmt.Println(end.Sub(start))
  37. }