Go 极简教程0.面试技能go

sync.Mutex 与 sync.WaitGroup 使用示例

2022-04-30  本文已影响0人  光剑书架上的书

使用 sync.Mutex 与 sync.WaitGroup

线程不安全的用法:

{
    var wg sync.WaitGroup
    count := 0
    for i := 0; i < 10; i++ {
        // wg add 1 goroutine
        wg.Add(1)
        // goroutine
        go func() {
            defer wg.Done()
            for i := 0; i < 10000; i++ {
                // unsafe increment
                count++
            }
        }()
    }

    wg.Wait()
    fmt.Println(count)
}

加锁,线程安全:

{
    var myLock sync.Mutex
    var wg sync.WaitGroup
    count := 0
    for i := 0; i < 10; i++ {
        // wg add 1 goroutine
        wg.Add(1)
        // goroutine
        go func() {
            defer wg.Done()
            for i := 0; i < 10000; i++ {
                // safe increment
                myLock.Lock()
                count++
                myLock.Unlock()
            }
        }()
    }

    wg.Wait()
    fmt.Println(count)
}

其中一个运行输出:
53546
100000

自定义一个safe Counter

package counter

import (
    "log"
    "sync"
)

type Counter struct {
    mu    *sync.Mutex
    Value int
}

func NewCounter(value int) *Counter {
    return &Counter{
        new(sync.Mutex), 0,
    }
}

func (c *Counter) Increment() {
    c.mu.Lock()
    // defer func
    defer func() {
        c.mu.Unlock()
        log.Printf("mu sync.Mutex Unlocked!")
    }()
    // safe increment Value
    c.Value++
}

使用 safe Counter

{
    var wg sync.WaitGroup
    count := counter.NewCounter(0)
    for i := 0; i < 10; i++ {
        // wg add 1 goroutine
        wg.Add(1)
        // goroutine
        go func() {
            defer wg.Done()
            for i := 0; i < 10000; i++ {
                // safe increment
                count.Increment()
            }
        }()
    }

    wg.Wait()
    fmt.Println(count.Value)
}

正确输出:
100000

上一篇下一篇

猜你喜欢

热点阅读