使用 atomic 或 Mutex 实现 Go 并发安全计数器:atomic 适用于简单增减,性能高;Mutex 适合复杂逻辑。示例中 AtomicCounter 通过 atomic.AddInt64 和 LoadInt64 实现无锁线程安全,最终输出 1000;MutexCounter 使用互斥锁保护 count 字段,支持条件判断等扩展操作。选择依据是场景复杂度:轻量操作选 atomic,复合逻辑选 Mutex。

在Go语言中实现并发安全的计数器,关键在于避免多个goroutine同时修改共享变量导致的数据竞争。可以通过 sync/atomic 包或 sync.Mutex 来实现线程安全的操作。
使用 atomic 实现轻量级原子计数器
atomic 提供了对基本数据类型的原子操作,适合简单的递增、递减场景,性能高且无需锁。
以下是一个基于 int64 的并发安全计数器示例:
package main
import (
"fmt"
"sync"
"sync/atomic"
)
type AtomicCounter struct {
count int64
}
func (c *AtomicCounter) Inc() {
atomic.AddInt64(&c.count, 1)
}
func (c *AtomicCounter) Value() int64 {
return atomic.LoadInt64(&c.count)
}
func main() {
var counter AtomicCounter
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Inc()
}()
}
wg.Wait()
fmt.Println("Final count:", counter.Value()) // 输出: 1000
}
使用 Mutex 保护复杂逻辑
当计数器需要附加逻辑(如限制最大值、条件判断)时,Mutex 更加灵活。
立即学习“go语言免费学习笔记(深入)”;
示例如下:
package main
import (
"fmt"
"sync"
)
type MutexCounter struct {
mu sync.Mutex
count int
}
func (c *MutexCounter) Inc() {
c.mu.Lock()
defer c.mu.Unlock()
c.count++
}
func (c *MutexCounter) Value() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.count
}
func main() {
var counter MutexCounter
var wg sync.WaitGroup
for i := 0; i < 1000; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Inc()
}()
}
wg.Wait()
fmt.Println("Final count:", counter.Value()) // 输出: 1000
}
如何选择?
根据使用场景决定实现方式:
- 只做简单增减,追求高性能 —— 用 atomic
- 涉及条件判断、复合操作或结构体字段联动 —— 用 Mutex
- 需要精确控制临界区或有较多读写混合操作时,Mutex 更易维护逻辑正确性
基本上就这些。atomic 更快更轻,Mutex 更通用。根据需求选合适的方式即可。










