sync.RWMutex | sync.WaitGroup | sync.NewCond | sync.Once | sync.Map |

package main

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

func main() {
    rw := sync.RWMutex{}
    //可以让多个协程同时读取某对象
    //初始值为解锁状态,通常作为其他结构体的匿名字段使用
    //可以安全的在多个协程中并行使用
    rw.Lock()    // 设置为写状态,禁止其他协程读取或写入
    rw.Unlock()  // 解锁状态,如果未被锁定---> panic
    rw.RLock()   // 设置为写状态,禁止其他协程写入;但是可以读取
    rw.RUnlock() // 解锁状态,如果未被锁定---> panic
    rw.RLocker() // 返回一个互斥锁,将rw.Rlock和rw.RUnlock封装过程一个Locker接口

    wg := sync.WaitGroup{}
    wg.Add(1) // 计数器加1,必须是正数
    wg.Done() // 计数器减1,直到归零,如果小于0,则该操作会引发panic
    wg.Wait()

    //条件等待,直到信号发送过来
    cond := sync.NewCond(new(sync.Mutex)) // 用一把锁

    for i := 0; i < 2; i++ {
        go func() {
            cond.L.Lock()
            cond.Wait() // 等待发送信号,消费一个信号
            fmt.Printf("%p\t%v\n", cond.L, cond.L)
            //time.Sleep(time.Second)
            cond.L.Unlock() // 多次wait  如果不释放锁,别的抢不到。
        }()
    }
    time.Sleep(time.Second) // 在发信号之前,要有等待的cond
    cond.Signal()           // 只唤醒 1个 等待c的goroutine
    cond.Signal()           // 只唤醒 1个 等待c的goroutine
    time.Sleep(time.Second * 2)

    on := sync.Once{}

    for i := 0; i < 2; i++ {
        go func() {
            fmt.Println("====")
            on.Do(func() {
                fmt.Println("-------")
            })
        }()
    }
    time.Sleep(time.Second)

    var syncMap sync.Map
    //并发操作一个map的时候,内置的map不是并发安全啊
    syncMap.Store("key1", "value1")
    fmt.Println(syncMap.Load("key"))
    syncMap.LoadOrStore("key2", "value2")
    syncMap.Delete("key")
    syncMap.Range(func(key, value interface{}) bool {
        fmt.Println(key, value)
        return true // 是否继续进行遍历
    })

}

 

posted @ 2020-02-11 21:35  慕沁  阅读(155)  评论(0)    收藏  举报