golang 之 sync包

sync.Map

  1. 并发操作一个map的时候内置的map不是并发安全的,需要初始化map才能使用
  2. sync.Map 是一个开箱即用的并发安全的不用初始化参数,定义一下参数,直接引用参数
  3. 使用方法:
    1. Store: 设置参数
    2. Load: 通过key获取值
    3. LoadOrStore:
    4. Delete:删除
    5. Rang:循环
复制代码
var syncMap sync.Map

syncMap.Store(key,value)
syncMap.Load(key)
syncMap.LoadOrStore()
syncMap.Delete()
syncMap.Range()
sync Map
复制代码

 

sync.WaitGroup

  1. 是一个结构体,是值类型,给结构体传参数的时候要传指针类型
  2.   使用开启goroutine时,main 的方法需要优雅的等待goroutine 都执行完成之后在关闭main的goroutine。  
  3.   使用方法:
    1. Add: 添加计数器
    2. Done: 删除计数器
    3. Wait: 等待计数器为0 

 

复制代码
package main

import (
    "fmt"
    "strconv"
    "sync"
)

/*
使用goroutine map 存值时候一定要使用sync.Map{}方式
内置的map 在goroutine时超过20个会报错,超过最大map限制
*/
var m2 = sync.Map{}
// 开启 sync.WaitGroup
var wg sync.WaitGroup

func goroutine_demo(){
    for i := 0; i< 10000;i++{
        
        wg.Add(1)
        go func(n int){
            key := strconv.Itoa(n)
            //必须使用sync.Map{}内置的Store方法设置键值对
            m2.Store(key,n)
            // 必须使用sync.Map{}提供的Load 方法根据key取值
            value,_ := m2.Load(key)   
            fmt.Printf("k=: %v, v=:%v\n",key,value)
            wg.Done()
        }(i)
    }
}
func main(){
    goroutine_demo()

}
sync map waitgroup
复制代码

 

sync.Mutex
  1. 锁,多个goroutine 同一时间操作公共资源时需要加锁,保证数据完整性
  2. 操作方法:
    1. Lock: 互斥锁
    2. Unlock: 解互斥锁
复制代码
package main

import (
    "fmt"
    "sync"
)

// globa ... x
var x = 0
var wg sync.WaitGroup

// 锁声明
var lock sync.Mutex
// add 
func add(){
    defer wg.Done()
    for i :=0 ; i < 1000; i++ {
        //加锁
        lock.Lock()
        x = x + 1
        // 释放锁
        lock.Unlock()
    }
}

func main(){
    wg.Add(2)
    go add()
    go add()
    wg.Wait()
    fmt.Println(x)

}
互斥锁
复制代码
sync.RWMutex
  1. 特点 
    1. 读的goroutine 时获取的是读锁后续的goroutine能读不能写

    2. 写的goroutine时获取的写锁,后续的goroutine不管读还是写都要等待获取锁

  2. 操作方法:
    1. RLock:锁
    2. RUnlock: 解锁
复制代码
package main

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

var (
    x  =  0
    wg sync.WaitGroup
    lock  sync.Mutex
    rwlock  sync.RWMutex
)

func read(){
    defer wg.Done()
    rwlock.RLock()
    // lock.Lock()
    fmt.Println(x)
    time.Sleep(time.Millisecond)
    rwlock.RUnlock()
    // lock.Unlock()
}

func write(){
    defer wg.Done()
    // lock.Lock()
    rwlock.RLock()
    x = x +1
    time.Sleep(time.Millisecond * 5)
    // lock.Unlock()
    rwlock.RUnlock()
}

func main(){
    start := time.Now()
    for i :=0 ; i < 10; i++{
        go write()
        wg.Add(1)
    }
    // time.Sleep(time.Second)
    for i :=0; i< 1000; i++{
        go read()
        wg.Add(1)
    }
    wg.Wait()
    fmt.Println(time.Now().Sub(start))
}
读写锁操作
复制代码

 sync.Once

某些函数只能执行一次的时候,就可以使用sync.Once

复制代码
var once sync.Once

func f2(ch1 <-chan int ,ch2 chan<- int){
    defer wg.Done()
    for {
        x,ok := <- ch1
        if !ok {
            break
        }
        ch2 <- x * x
    }
    // 确保某个操作只执行一次
    once.Do(func() { close(ch2) })
}
sync once
复制代码

 

 
posted @   扛把子修BUG  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
点击右上角即可分享
微信分享提示