互斥锁(Mutex)是 Go 语言中最基础、最常用的并发控制方式之一,其主要目的是在不同的 goroutine 中保护共享资源,保证同一时间只有一个 goroutine 能够访问该资源,避免竞态条件(Race Condition)的发生。
互斥锁最常见的应用场景是对共享的数据结构进行读写操作。在 Go 语言中,map 是一种常见的数据结构,在多个 goroutine 并发读写时需要使用互斥锁来保证操作的安全性。
下面是一个简单的示例,演示了如何使用互斥锁对 map 进行并发读写操作:
package main
import (
"fmt"
"sync"
)
var m map[int]intvar lock sync.Mutex
funcmain() {
m = make(map[int]int)
wg := sync.WaitGroup{}
wg.Add(2)
go func() {
defer wg.Done()
for i := 0; i < 100000; i++ {
lock.Lock()
m[i] = i
lock.Unlock()
}
}()
go func() {
defer wg.Done()
for i := 0; i < 100000; i++ {
lock.Lock()
delete(m, i)
lock.Unlock()
}
}()
wg.Wait()
fmt.Println(len(m))
}
在这个示例中,我们使用了一个互斥锁 lock 来保护 map m 的读写操作。在第一个 goroutine 中,我们往 map 中添加了 100000 个键值对;在第二个 goroutine 中,我们删除了 map 中的 100000 个键值对。
使用互斥锁的好处是能够保证在同一时刻只有一个 goroutine 能够访问被保护的共享资源,从而避免了数据竞争。不过,过度使用互斥锁也会带来一些副作用,比如降低程序的性能,增加程序的复杂度等等,因此在实际开发中需要根据具体情况权衡使用。
除了 map 之外,互斥锁还可以用于其他类型的共享数据结构的读写操作,比如 slice、数组、链表等