互斥锁

  • sync.mutex
  • 获取到锁的任务,阻塞其他任务
  • 意味着同一时间只有一个go才能持有锁
  • 互斥锁举例 ```go package main

import ( “log” “sync” “time” )

var HcMutex sync.Mutex

func runMutex(id int) { log.Printf(“[任务id:%d][尝试获取锁]”, id) HcMutex.Lock() log.Printf(“[任务id:%d][获取到了锁][开始干活:睡眠10秒]”, id) time.Sleep(10 * time.Second) HcMutex.Unlock() log.Printf(“[任务id:%d][干完活了 释放锁]”, id) }

func runHcLock() { go runMutex(1) go runMutex(2) go runMutex(3) }

func main() { // 执行互斥锁 效果任务 runHcLock()

  1. time.Sleep(600 * time.Second) //演示使用,目的是不让主线程延迟退出

}

  1. <a name="kwcAP"></a>
  2. ## **读写锁**
  3. - sync.rwmutex
  4. - 写锁阻塞所有锁(所有读锁和写锁) ,目的是修改时其他人不要读取,也不要修改
  5. - 读锁阻塞写锁 ,读锁可以同时施加多个 。目的 不要让修改数据影响我的读取结果
  6. - 同时多个读任务, 可以施加多个读锁,阻塞写锁
  7. - 同时多个写任务 ,只可以施加一个写锁,阻塞其他所有锁 ,退化成互斥锁
  8. - 读写混合:若有写锁,等待释放后能施加 读或写
  9. - 读写混合:若有读锁,只能再施加读锁,阻塞写锁
  10. ```go
  11. package main
  12. import (
  13. "log"
  14. "sync"
  15. "time"
  16. )
  17. var HcMutex sync.Mutex
  18. var rwMutex sync.RWMutex
  19. func runMutex(id int) {
  20. log.Printf("[任务id:%d][尝试获取锁]", id)
  21. HcMutex.Lock()
  22. log.Printf("[任务id:%d][获取到了锁][开始干活:睡眠10秒]", id)
  23. time.Sleep(10 * time.Second)
  24. HcMutex.Unlock()
  25. log.Printf("[任务id:%d][干完活了 释放锁]", id)
  26. }
  27. func runHcLock() {
  28. go runMutex(1)
  29. go runMutex(2)
  30. go runMutex(3)
  31. }
  32. func runReadLock(id int) {
  33. log.Printf("[读任务:%d][进入读方法等待获取读锁]", id)
  34. rwMutex.RLock()
  35. log.Printf("[读任务:%d][获取到了读锁][干活:睡眠10秒]", id)
  36. time.Sleep(10 * time.Second)
  37. rwMutex.RUnlock()
  38. log.Printf("[读任务:%d][完成读任务,释放读锁]",id)
  39. }
  40. func runWriteLock(id int) {
  41. log.Printf("[写任务:%d][进入写方法等待获取写锁]", id)
  42. rwMutex.Lock()
  43. log.Printf("[写任务:%d][获取到了写锁][干活:睡眠10秒]", id)
  44. time.Sleep(10 * time.Second)
  45. rwMutex.Unlock()
  46. log.Printf("[写任务:%d][完成写任务,释放写锁]",id)
  47. }
  48. func allWriteWorks() {
  49. for i := 1; i < 6; i++ {
  50. go runWriteLock(i)
  51. }
  52. }
  53. func allReadWorks() {
  54. for i := 1; i < 6; i++ {
  55. go runReadLock(i)
  56. }
  57. }
  58. func writeFirst() {
  59. go runWriteLock(1)
  60. time.Sleep(1 * time.Second)
  61. go runReadLock(1)
  62. go runReadLock(2)
  63. go runReadLock(3)
  64. go runReadLock(4)
  65. go runReadLock(5)
  66. }
  67. func readFirst() {
  68. go runReadLock(1)
  69. go runReadLock(2)
  70. go runReadLock(3)
  71. go runReadLock(4)
  72. go runReadLock(5)
  73. time.Sleep(1 * time.Second)
  74. go runWriteLock(1)
  75. }
  76. func main() {
  77. // 执行互斥锁 效果任务
  78. //runHcLock()
  79. // 同时多个写锁任务,说明如果 并非使用 读写锁的写锁任务时,退化成了互斥锁
  80. //allWriteWorks()
  81. // 同时并发 读锁任务, 说明读写锁的读锁 是可以同时施加多个读锁的
  82. //allReadWorks()
  83. // 先启动写锁任务,后并非5个读锁任务,当有写锁时,读锁施加不了,写锁释放完,读锁可以施加多个
  84. //writeFirst()
  85. // 并发5个读锁任务,启动一个写锁任务, 当有读锁时,阻塞写锁
  86. readFirst()
  87. time.Sleep(6000 * time.Second)
  88. }