• 典型并发任务


    • 只运行一次

    懒汉式,线程安全

    var once sync.Once
    var obj *SingletonObj
    
    func GetSingletonObj() *SingletonObj {
        once.Do(func() {
            fmt.Println("Create Singleton obj.")
            obj = &SingletonObj{}
        })
        return obj
    }
    package once_test
    
    import "sync"
    
    type Singleton struct{
    
    }
    
    var singleInstance *Singleton
    var once sync.Once
    
    func GetSingletonObj() *Singleton {
        once.Do(func() {
            fmt.Println("Create Obj")
            singleInstance = new(Singleton)
        })
        return singleInstance
    }
    
    func TestGetSingletonObj(t *testing.T) {
        var wg sync.WaitGroup
        for i:=0; I<10; I++{
            wg.Add(1)
            go func() {
                obj := GetSingletonObj()
                fmt.Printf("%x
    ", unsafe.Pointer(obj))
                wg.Done()
            }()
        }
        wg.Wait()
    }
    • 仅需任意任务完成

    CSP

    func runTask(id int) string {
        time.Sleep(10 * time.Millisecond)
        return fmt.Sprintf("The result is from %d", id)
    }
    
    func FirstResponse() string {
        numOfRunner := 10
        ch := make(chan string, numOfRunner)
        for i := 0; i < numOfRunner; i++{
            go func(I int) {
                ret := runTask(i)
                ch <- ret
            }(i)
        }
        return <-ch  //channel的阻塞机制
    }
    
    func TestFirstResponse(t *testing.T) {
        t.Log("Before:",runtime.NumGoroutine())
        t.Log(FirstRespoonse())
        t.Log("Befor:",runtime.NumGoroutine())
    }
    • 所有任务完成

    sync.wg

    CSP

    func runTask(id int) string {
        time.Sleep(10 * time.Millisecond)
        return fmt.Sprintf("The result is from %d", id)
    }
    
    func AllResponse() string {
        numOfRunner := 10
        ch := make(chan string, numOfRunner)
        for i := 0; i < numOfRunner; i++{
            go func(I int) {
                ret := runTask(i)
                ch <- ret
            }(i)
        }
        finalRet := ""
        for j:=0;j<numOfRunner;j++{
            finalRet += <-ch + "
    "
        }
        return finalRet
    }
    
    func TestAllResponse(t *testing.T) {
        t.Log("Before:",runtime.NumGoroutine())
        t.Log(AllRespoonse())
        t.Log("Befor:",runtime.NumGoroutine())
    }
    • 对象池

    数据库连接、网络连接

    使用buffered channel实现对象池

    • sync.pool对象缓存

    sync.Pool对象获取

    尝试从私有对象获取(私有对象:协程安全;共享池:协程不安全的)

    私有对象不存在,尝试从当前Processor的共享池获取

    如果当前Processor共享池也是空的,那么就尝试去其他Processor的共享池获取

    如果所有子池都是空的,最后就用用户指定的New函数产生一个新的对象返回

    sync.Pool对象的放回

    如果私有对象不存在则保存为私有对象

    如果私有对象存在,放入当前Processor子池的共享池中

    使用sync.Pool

    pool := &sync.Pool{
        New: func() interface{} {
            return 0
        },
    }
    
    array := pool.Get().(int)
    ...
    pool.Put(10)

    sync.Pool对象的生命周期

    GC会清除sync.pool缓存的对象;对象的缓存有效期为下一次GC之前 

  • 相关阅读:
    一种client同步server数据的方案
    nodejs package.json解释
    node.js JS对象和JSON字符串之间的转换
    setInterval的用法
    ActiveMQ 入门Nodejs版
    ActiveMQ + NodeJS + Stomp 极简入门
    为什么 ++[[]][+[]]+[+[]] = 10?
    Child Process模块
    phantomjs 解码url
    PhantomJSのメモいろいろ
  • 原文地址:https://www.cnblogs.com/liushoudong/p/13085853.html
Copyright © 2020-2023  润新知