面试题答案
一键面试- 使用同步原语确保数据一致性和线程安全的原理:
- Mutex(互斥锁):用于保护共享资源,在同一时间只允许一个Goroutine访问共享资源。当一个Goroutine获取了Mutex锁,其他Goroutine必须等待锁被释放才能访问共享资源,从而避免数据竞争。
- WaitGroup:用于等待一组Goroutine完成。它内部维护一个计数器,通过
Add
方法增加计数器的值,通过Done
方法减少计数器的值,Wait
方法会阻塞直到计数器的值变为0。
- 代码实现:
package main
import (
"fmt"
"sync"
)
func main() {
var counter int
var mu sync.Mutex
var wg sync.WaitGroup
numGoroutines := 5
wg.Add(numGoroutines)
for i := 0; i < numGoroutines; i++ {
go func() {
defer wg.Done()
for j := 0; j < 100; j++ {
mu.Lock()
counter++
mu.Unlock()
}
}()
}
wg.Wait()
fmt.Println("Final counter value:", counter)
}
在上述代码中:
- 定义了一个共享的计数器
counter
。 - 使用
sync.Mutex
来保护counter
的访问,在每次对counter
进行累加操作前,通过mu.Lock()
获取锁,操作完成后通过mu.Unlock()
释放锁。 - 使用
sync.WaitGroup
来等待所有Goroutine完成累加操作。wg.Add(numGoroutines)
设置需要等待的Goroutine数量,每个Goroutine在完成任务后调用wg.Done()
,wg.Wait()
会阻塞主线程直到所有Goroutine都调用了wg.Done()
。最后输出正确的累加结果,理论上counter
的值应该是numGoroutines * 100
,即500
。