使用sync.Mutex
确保并发安全
- 适用场景:当读写操作频繁且对写操作有强一致性要求,每次只允许一个 goroutine 进行读写操作时使用。因为
sync.Mutex
是互斥锁,同一时间只有一个 goroutine 能获取锁,进行读写,这能保证数据的一致性,但在高并发读场景下性能较差。
- 实现方式:
package main
import (
"fmt"
"sync"
)
var (
dataMap = make(map[string]int)
mu sync.Mutex
)
func write(key string, value int) {
mu.Lock()
dataMap[key] = value
mu.Unlock()
}
func read(key string) int {
mu.Lock()
value := dataMap[key]
mu.Unlock()
return value
}
使用sync.RWMutex
确保并发安全
- 适用场景:当读操作远多于写操作时使用。
sync.RWMutex
允许多个 goroutine 同时读数据,只有在写操作时才需要独占锁,这样可以提高读性能。但如果写操作过于频繁,会导致读操作长时间等待写操作完成,从而降低整体性能。
- 实现方式:
package main
import (
"fmt"
"sync"
)
var (
dataMap = make(map[string]int)
rwmu sync.RWMutex
)
func write(key string, value int) {
rwmu.Lock()
dataMap[key] = value
rwmu.Unlock()
}
func read(key string) int {
rwmu.RLock()
value := dataMap[key]
rwmu.RUnlock()
return value
}
性能差异分析
sync.Mutex
:由于每次读写都要独占锁,在高并发读场景下,会造成大量的 goroutine 等待锁的释放,从而导致性能瓶颈。但对于写操作频繁且需要强一致性的场景,它能保证数据的正确性。
sync.RWMutex
:读操作时允许多个 goroutine 同时进行,大大提高了读性能。但写操作会独占锁,若写操作频繁,会使读操作等待时间变长。所以在读写比例不均衡,读操作远多于写操作时,sync.RWMutex
性能更优;而在读写操作比较均衡或者写操作频繁时,sync.Mutex
可能更合适,具体要根据实际应用场景的读写比例和性能要求来选择。