- 实现思路:
- 互斥锁(Mutex):使用
sync.Mutex
来保护共享资源。在访问共享资源前加锁,访问完成后解锁。这样同一时间只有一个协程能访问共享资源,避免数据竞争。
- 读写锁(RWMutex):如果对共享资源的读操作远多于写操作,可以使用
sync.RWMutex
。读操作时可以多个协程同时进行(加读锁),写操作时则需要独占(加写锁),以保证数据一致性。
- 代码示例(使用互斥锁):
package main
import (
"fmt"
"sync"
)
var (
counter int
mu sync.Mutex
)
func increment(wg *sync.WaitGroup) {
defer wg.Done()
mu.Lock()
counter++
mu.Unlock()
}
func main() {
var wg sync.WaitGroup
numRoutines := 1000
for i := 0; i < numRoutines; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final counter value:", counter)
}
- 代码示例(使用读写锁,假设读多写少场景):
package main
import (
"fmt"
"sync"
"time"
)
var (
data int
rwmu sync.RWMutex
)
func read(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.RLock()
fmt.Printf("Read value: %d\n", data)
rwmu.RUnlock()
}
func write(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.Lock()
data++
fmt.Printf("Write new value: %d\n", data)
rwmu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go read(&wg)
}
for i := 0; i < 2; i++ {
wg.Add(1)
go write(&wg)
}
time.Sleep(2 * time.Second)
wg.Wait()
}