互斥锁
若不加互斥锁,下面这段程序中map[1]的数值可能为负数(多次执行结果可能不相同,但大多都为负数)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| var lock sync.Mutex
func consumer(m map[int]int) { // 定义一个消费者,用来消费传入的map中的数值,直到数值小于或等于0 // 在没有使用互斥锁时,map中的数值可能会出现负数 // 读写锁适合在读写频率相差不多的情况下使用,其会影响性能 for i := 0; i < 100; i++ { go func(m1 map[int]int) { lock.Lock() //上锁 if m1[1] > 0 { time.Sleep(time.Microsecond) m1[1] = m1[1] - 1 } lock.Unlock() //解锁 }(m) } }
func test1() { m := make(map[int]int, 1) m[1] = 10 consumer(m) time.Sleep(3 * time.Second) fmt.Printf("map:%v", m) }
func main() { test1() } --------------------- map:map[1:0]
|
读写锁
下面这段程序可以看出:在读锁时,两个读操作可以并发执行, 而在写锁时,只有一个写锁释放了,另一个写锁才会执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
| var rwlock sync.RWMutex
func read(i int) { fmt.Println(i, "read start") rwlock.RLock() start := 0 pr := "read"
for { if start > 10 { break } time.Sleep(time.Millisecond) pr += "." fmt.Println(i, pr) start++ } rwlock.RUnlock() fmt.Println(i, "read end") }
func write(i int) { fmt.Println(i, "write start") rwlock.Lock() start := 0 pr := "write"
for { if start > 10 { break } time.Sleep(time.Millisecond) pr += "." fmt.Println(i, pr) start++ } rwlock.Unlock() fmt.Println(i, "write end") }
func test2() { // 读写锁,适合用在读多写少的情况下 // 进行读操作的时候无需等待读锁的结束 go read(1) go write(1) go read(2) go write(2) time.Sleep(time.Second * 5)
}
func main() { test2() } -------------------------- 1 read start 2 read start 1 write start 2 write start 1 read. 2 read. 1 read.. 2 read.. 1 read... 1 read.... 2 read... 2 read.... 1 read..... 2 read..... 1 read...... 1 read....... 2 read...... 1 read........ 2 read....... 1 read......... 2 read........ 2 read......... 1 read.......... 2 read.......... 1 read........... 1 read end 2 read........... 2 read end 1 write. 1 write.. 1 write... 1 write.... 1 write..... 1 write...... 1 write....... 1 write........ 1 write......... 1 write.......... 1 write........... 1 write end 2 write. 2 write.. 2 write... 2 write.... 2 write..... 2 write...... 2 write....... 2 write........ 2 write......... 2 write.......... 2 write........... 2 write end
|