go原子操作 atomic
原子操作可以实现和sync.mux一样的
package main
import (
"fmt"
"sync"
)
var mux sync.Mutex
func main() {
var count int32
fmt.Println("main start...")
var wg sync.WaitGroup
for i:=0;i<50000;i++ {
wg.Add(1)
go func( i int){
defer wg.Done()
//fmt.Println("goroutine:",i,"start...")
//atomic.AddInt32(&count,1)
//count++
mux.Lock()
count++
mux.Unlock()
//fmt.Println("goroutine:",i,"count:",count,"end...")
}(i)
}
wg.Wait()
fmt.Println(count)
fmt.Println("main end...")
}
package main
import (
"fmt"
"sync"
)
var mux sync.Mutex
func main() {
var count int32
fmt.Println("main start...")
var wg sync.WaitGroup
for i:=0;i<50000;i++ {
wg.Add(1)
go func( i int){
defer wg.Done()
//fmt.Println("goroutine:",i,"start...")
//atomic.AddInt32(&count,1)
//count++
mux.Lock()
count++
mux.Unlock()
//fmt.Println("goroutine:",i,"count:",count,"end...")
}(i)
}
wg.Wait()
fmt.Println(count)
fmt.Println("main end...")
}
count++ 只有这个的时候结果不是五万
下面两个的结果都正确
mux.Lock()
count++
mux.Unlock()
atomic.AddInt32(&count,1)
package main
import (
"fmt"
"sync"
"sync/atomic"
"time"
)
type Counter interface {
Inc()
Load() int64
}
// 普通版
type CommonCounter struct {
counter int64
}
func (c *CommonCounter) Inc() {
c.counter++
}
func (c *CommonCounter) Load() int64 {
return c.counter
}
// 互斥锁版
type MutexCounter struct {
counter int64
lock sync.Mutex
}
func (m *MutexCounter) Inc() {
m.lock.Lock()
defer m.lock.Unlock()
m.counter++
}
func (m *MutexCounter) Load() int64 {
m.lock.Lock()
defer m.lock.Unlock()
return m.counter
}
// 原子操作版
type AtomicCounter struct {
counter int64
}
func (a *AtomicCounter) Inc() {
atomic.AddInt64(&a.counter, 1)
}
func (a *AtomicCounter) Load() int64 {
return atomic.LoadInt64(&a.counter)
}
func test(c Counter) {
var wg sync.WaitGroup
start := time.Now()
for i := 0; i < 2000; i++ {
wg.Add(1)
go func() {
c.Inc()
wg.Done()
}()
}
wg.Wait()
end := time.Now()
fmt.Println(c.Load(), end.Sub(start))
}
func main() {
c1 := CommonCounter{} // 非并发安全
test(&c1)
c2 := MutexCounter{} // 使用互斥锁实现并发安全
test(&c2)
c3 := AtomicCounter{} // 并发安全且比互斥锁效率更高
test(&c3)
}