go原子操作 atomic

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)
}