使用sync.Mutex保护共享变量可实现Go并发安全计数器。2. 定义含互斥锁和计数字段的结构体,通过加锁解锁保证读写操作的原子性。3. 示例代码展示Inc和Value方法加锁操作,main函数中多goroutine并发调用并等待完成,确保数据竞争安全。

在Go语言中实现并发安全的计数器,关键在于避免多个goroutine同时修改共享变量导致的数据竞争。直接使用普通变量加自增操作(如 i++)在并发场景下是不安全的。要正确实现,必须借助同步机制。
使用 sync.Mutex 保护计数器
最直观的方式是用 sync.Mutex 来保护对计数器的访问,确保同一时间只有一个goroutine能修改值。
定义一个结构体包含计数器数值和互斥锁 每次读写计数器前先加锁,操作完成后解锁
示例代码:
package mainimport ( "fmt" "sync")type Counter struct { mu sync.Mutex count int}func (c *Counter) Inc() { c.mu.Lock() defer c.mu.Unlock() c.count++}func (c *Counter) Value() int { c.mu.Lock() defer c.mu.Unlock() return c.count}func main() { var counter Counter var wg sync.WaitGroup for i := 0; i < 1000; i++ { wg.Add(1) go func() { defer wg.Done() counter.Inc() }() } wg.Wait() fmt.Println("计数器最终值:", counter.Value()) // 输出: 1000}
使用 sync/atomic 实现无锁计数器
对于简单的递增操作,推荐使用 sync/atomic 包提供的原子操作。它性能更高,且无需锁。
立即学习“go语言免费学习笔记(深入)”;
使用 atomic.AddInt64 或 atomic.LoadInt64 等函数 避免了锁开销,适合高并发场景
示例代码:
package mainimport ( "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("原子计数器最终值:", counter.Value()) // 输出: 1000}
选择合适的实现方式
如果只是做递增、递减或读取,优先使用 atomic。它的操作是底层硬件支持的原子指令,效率高且不会阻塞goroutine。
当计数器逻辑更复杂(比如需要条件判断后再更新),则使用 mutex 更清晰安全。
基本上就这些。掌握这两种方式,就能在Go中稳妥地处理并发计数需求。关键是理解数据竞争的本质,并选择合适工具避免它。
以上就是如何在Golang中实现并发安全计数器_Golang 并发计数器实践的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1425792.html
微信扫一扫
支付宝扫一扫