sync.Mutex 与 sync.WaitGroup 使用示例

2022-05-13 15:06:12 浏览数 (2)

使用 sync.Mutex 与 sync.WaitGroup

线程不安全的用法:

代码语言:javascript复制
{
    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)
}

加锁,线程安全:

代码语言:javascript复制
{
    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

代码语言:javascript复制
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

代码语言:javascript复制
{
    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

0 人点赞