互斥锁

代码示例

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    //声明
    var mutex sync.Mutex
    fmt.Println("Lock the lock. (G0)")
    //加锁mutex
    mutex.Lock()

    fmt.Println("The lock is locked.(G0)")
    for i := 1; i < 4; i++ {
        go func(i int) {
            fmt.Printf("----Lock the lock. (G%d)\n", i)
            mutex.Lock()
            fmt.Printf("++++The lock is locked. (G%d)\n", i)
        }(i)
    }
    //休息一会,等待打印结果
    time.Sleep(time.Second)
    fmt.Println("Unlock the lock. (G0)")
    //解锁mutex
    mutex.Unlock()

    fmt.Println("The lock is unlocked. (G0)")
    //休息一会,等待打印结果
    time.Sleep(time.Second)
    Lock the lock. (G0)
    // 同一个互斥锁的成对锁定和解锁操作放在同一层次的代码块中。
}

打印结果

Lock the lock. (G0)
The lock is locked.(G0)
----Lock the lock. (G2)
----Lock the lock. (G1)
----Lock the lock. (G3)
Unlock the lock. (G0)
The lock is unlocked. (G0)
++++The lock is locked. (G2) //随机 G1 G2 G3

使用互斥锁的注意事项如下:

goroutinegoroutineLockpanicsync.Mutex

建议:尽量避免把一个互斥锁同时用在了多个地方,多个goroutine 争用这把锁增大死锁可能性。而最简单、有效的方式就是让每一个互斥锁都只保护一个临界区或一组相关临界区。

读写锁

sync.RWMutex