如何在Golang中实现并发累加器_多协程安全计算总和

使用 sync.Mutex 保护共享变量最直接的方式是用互斥锁确保同一时间只有一个协程能修改累加器,定义 Counter 结构体封装值和锁,Add 方法先加锁再更新,读取也建议加锁;atomic.AddInt64 更轻量高效但需 int64 类型;channel 方式适合任务分片,各协程发局部和到通道,主协程统一累加。

使用 sync.Mutex 保护共享变量

最直接的方式是用互斥锁确保同一时间只有一个协程能修改累加器。定义一个结构体封装值和锁,所有加法操作都先加锁再更新:

  • 声明 type Counter struct { mu sync.Mutex; total int }
  • 提供 Add(n int) 方法:调用 c.mu.Lock() → 修改 c.total += nc.mu.Unlock()
  • 读取时也建议加锁(如 Value() 方法),避免读到中间状态

用 sync/atomic 实现无锁累加

当只做整数加减且平台支持时,atomic.AddInt64 更轻量高效。注意变量必须是 int64 类型(32 位系统上 int 可能非原子):

  • 声明 var total int64(不能是 int 或 int32)
  • 各协程调用 atomic.AddInt64(&total, int64(n)) 安全累加
  • 最终读取用 atomic.LoadInt64(&total),不需锁

用 channel 汇总结果(适合任务分片场景)

若每个协程负责处理一部分数据,可让它们把局部和发到通道,由主协程统一累加:

  • 启动 N 个协程,每个处理子数组并发送 sumch := make(chan int64, N)
  • 主协程循环接收:for i := 0; i
  • 避免共享内存竞争,逻辑清晰,但有 goroutine 和 channel 开销

使用 sync.WaitGroup 协调完成时机

无论选哪种累加方式,都要等所有协程结束才能获取最终结果。WaitGroup 是标准做法:

  • 创建 var wg sync.WaitGroup
  • 每启一个协程前调用 wg.Add(1),协程末尾调用 wg.Done()
  • 主协程用 wg.Wait() 阻塞直到全部完成