zoukankan      html  css  js  c++  java
  • 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)
    }
    
  • 相关阅读:
    PLSQL Developer个性化设置
    MyEclipse个性化设置
    log4j:WARN No appenders could be found for logger
    spring调用方法(接口和多个实现类的情况)
    配置tomcat报错: Unknown version of Tomcat was specified.
    软件设计模式六大原则
    Java中子类是否可以继承父类的static变量和方法而呈现多态特性
    网络端口集合
    [OJ] Permutation Index
    [OJ] Matrix Zigzag Traversal
  • 原文地址:https://www.cnblogs.com/brady-wang/p/15092717.html
Copyright © 2011-2022 走看看