面试题答案
一键面试实际场景
- 计数器场景:在高并发环境下对计数器进行操作,避免多个goroutine同时修改计数器值导致数据不一致。例如,在分布式系统的监控指标统计中,多个节点可能同时更新某个指标的计数。
- 资源分配场景:如连接池管理,需要决定某个连接是否可以被分配给新的请求。当多个请求同时竞争连接时,要确保只有一个请求能成功获取连接。
使用方法示例(以计数器场景为例)
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
numGoroutines := 100
for i := 0; i < numGoroutines; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := 0; j < 100; j++ {
for {
old := atomic.LoadInt64(&counter)
new := old + 1
if atomic.CompareAndSwapInt64(&counter, old, new) {
break
}
}
}
}()
}
wg.Wait()
fmt.Printf("Final counter value: %d\n", atomic.LoadInt64(&counter))
}
在上述代码中,atomic.CompareAndSwapInt64
函数用于实现高并发下计数器的安全自增。首先,通过atomic.LoadInt64
获取计数器的当前值old
,然后计算新值new
。接着,使用atomic.CompareAndSwapInt64
尝试将计数器的值从old
更新为new
。如果更新成功(即当前计数器的值仍然是old
,表示没有其他goroutine在这期间修改它),则跳出循环;否则,重新获取当前值并重复上述过程。这样就保证了在并发环境下计数器的操作是线程安全的。