在 Go 语言中,也存在类似的问题,当多个 Goroutine 同时访问和修改共享变量时,会出现竞态条件(Race Condition)。为了避免这种情况,可以使用以下几种方法:
方法一:使用互斥锁(Mutex)
使用 sync 包中的 Mutex 来保护共享变量的访问。
go
Copy
package main
import (
"fmt"
"sync"
)
func main() {
var i int
var mu sync.Mutex
var wg sync.WaitGroup
for j := 0; j < 1000; j++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
i++
mu.Unlock()
}()
}
wg.Wait()
fmt.Println("Final value of i:", i)
}
package main
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var i int32
var wg sync.WaitGroup
for j := 0; j < 1000; j++ {
wg.Add(1)
go func() {
defer wg.Done()
atomic.AddInt32(&i, 1)
}()
}
wg.Wait()
fmt.Println("Final value of i:", i)
}
在这个例子中,atomic.AddInt32(&i, 1) 确保了 i 的自增操作是原子的,不会被其他 Goroutine 干扰。
方法三:使用通道(Channels)
Go 提供了通道(Channels),可以用于在 Goroutine 之间传递数据,避免共享内存的直接修改。
go
Copy
package main
import (
"fmt"
"sync"
)
func main() {
var i int
var wg sync.WaitGroup
ch := make(chan bool)
for j := 0; j < 1000; j++ {
wg.Add(1)
go func() {
defer wg.Done()
ch <- true
}()
}
go func() {
for range ch {
i++
}
}()
wg.Wait()
close(ch) // 关闭通道,确保所有数据都被处理
fmt.Println("Final value of i:", i)
}