Golang sync包常用并发工具实践

sync包提供Mutex、RWMutex、WaitGroup等工具解决并发问题:Mutex确保共享资源互斥访问,防止数据竞争;RWMutex在读多写少场景允许多个读操作并发,提升性能;WaitGroup用于等待一组goroutine完成任务,协调协程生命周期。

Golang sync包常用并发工具实践

Go语言通过内置的 sync 包为并发编程提供了高效且易于使用的同步原语。在实际开发中,合理使用这些工具能有效避免竞态条件、保证数据一致性,并提升程序的稳定性。下面介绍几种 sync 包中最常用的并发控制工具及其典型应用场景。

sync.Mutex:保护共享资源的基本锁

当多个goroutine需要访问和修改同一块共享数据时,必须使用互斥锁来防止数据竞争。sync.Mutex 是最基础的同步机制

使用方式简单:在读写共享变量前调用 Lock(),操作完成后调用 Unlock()。注意要配合 defer 使用,确保解锁不会被遗漏。

示例:计数器安全递增

立即学习go语言免费学习笔记(深入)”;

var mu sync.Mutex
var count int

func increment() {
  mu.Lock()
  defer mu.Unlock()
  count++
}

如果不加锁,多个goroutine同时执行 count++ 可能导致结果不准确。加上Mutex后,每次只有一个goroutine能修改 count,保障了正确性。

sync.RWMutex:读多写少场景的优化选择

在某些场景下,数据被频繁读取但很少修改,比如配置缓存。此时使用 sync.RWMutex 能显著提升性能,它允许多个读操作并发进行,只在写操作时独占访问。

读锁使用 RLock()RUnlock(),写锁仍用 Lock()/Unlock()

示例:线程安全的配置读取

var rwMu sync.RWMutex
var config map[String]string

func GetConfig(key string) string {
  rwMu.RLock()
  defer rwMu.RUnlock()
  return config[key]
}

func UpdateConfig(key, value string) {
  rwMu.Lock()
  defer rwMu.Unlock()
  config[key] = value
}

多个goroutine可同时调用 GetConfig,只有 UpdateConfig 会阻塞读操作。

sync.WaitGroup:等待一组goroutine完成

当需要启动多个goroutine并等待它们全部结束时,sync.WaitGroup 是理想选择。它通过计数机制协调主协程与子协程的生命周期。

Golang sync包常用并发工具实践

黑点工具

在线工具导航网站,免费使用无需注册,快速使用无门槛。

Golang sync包常用并发工具实践18

查看详情 Golang sync包常用并发工具实践

核心方法有三个:Add(n) 增加计数,Done() 表示一个任务完成(相当于 Add(-1)),Wait() 阻塞直到计数归零。

常见模式:

var wg sync.WaitGroup

for i := 0; i   wg.Add(1)
  go func(i int) {
    defer wg.Done()
    fmt.Println(“worker”, i)
  }(i)
}
wg.Wait()
fmt.Println(“all workers done”)

注意:Add 应在 go 语句前调用,避免因调度延迟导致 Wait 提前结束。

sync.Once:确保初始化仅执行一次

有些操作如加载配置、初始化连接池等,必须且只能执行一次。sync.Once 提供了线程安全的“单次执行”保障。

只需定义一个 sync.Once 变量,并调用其 Do(f) 方法,传入要执行的函数。

示例:单例模式中的安全初始化

var once sync.Once
var instance *MySingleton

func GetInstance() *MySingleton {
  once.Do(func() {
    instance = &MySingleton{}
    // 初始化逻辑
  })
  return instance
}

即使多个goroutine同时调用 GetInstance,内部的初始化函数也只会执行一次。

基本上就这些。掌握 Mutex、RWMutex、WaitGroup 和 Once 的使用,已经能应对大多数并发场景下的同步需求。关键是理解每种工具的设计意图和适用边界,避免过度加锁或误用导致死锁与性能下降。

上一篇
下一篇
text=ZqhQzanResources