MST

星途 面试题库

面试题:Go语言中atomic.CompareAndSwap的使用场景举例

请举例说明在Go语言中,哪些实际场景下会用到atomic.CompareAndSwap函数,并且简要描述如何使用它来解决该场景中的并发问题。
27.5万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

实际场景

  1. 计数器场景:在高并发环境下对计数器进行操作,避免多个goroutine同时修改计数器值导致数据不一致。例如,在分布式系统的监控指标统计中,多个节点可能同时更新某个指标的计数。
  2. 资源分配场景:如连接池管理,需要决定某个连接是否可以被分配给新的请求。当多个请求同时竞争连接时,要确保只有一个请求能成功获取连接。

使用方法示例(以计数器场景为例)

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在这期间修改它),则跳出循环;否则,重新获取当前值并重复上述过程。这样就保证了在并发环境下计数器的操作是线程安全的。