Golang学习笔记-sync

土豆吞噬者 · · 600 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

Mutex

  • sync.Mutex为互斥锁,同一时间只能有一个goroutine获得互斥锁。
  • 使用Lock()加锁,Unlock()解锁,加锁前不能解锁,加锁后不能继续加锁。
  • 已经锁定的 Mutex 并不与特定的 goroutine 相关联,可以利用一个 goroutine 对其加锁,再利用其他 goroutine 对其解锁。
  • 适用于同一时间只能有一个goroutine访问资源的场景。

下面的代码如果不使用Mutex,输出的会是1 1 2 2 3 3而不是1 2 3 1 2 3。

package main

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

var (
    mutex sync.Mutex
)

func print123(){
    mutex.Lock()
    defer mutex.Unlock()
    for i:=0;i<3;i++{
        fmt.Println(i+1)
        time.Sleep(time.Millisecond*100)
    }
}

func main(){
    go print123()
    go print123()
    time.Sleep(time.Second*5)
}

RWMutex

  • sync.RWMutex为读写锁,同一时间可以有多个goroutine获得读锁或者一个goroutine获得写锁。
  • 使用Lock()加写锁,Unlock()解写锁,RLock()加读锁,RUnlock()解读锁,读锁可以加多个,解读锁的次数不能多于加读锁的次数。
  • 适用于同一时间可以有多个goroutine对资源进行读操作或一个goroutine对资源进行写操作的场景。
  • 读少写多的情况下使用Mutex,其它情况下RWMutex性能更好。

Map

Go内建的map不是线程安全的,所以之前都会使用加锁的方式控制对map的并发访问,而在新版本中可以使用sync.Map代替map+RWMutex,sync.Map相比后者有更好的性能,下面是sync.Map的基本使用方法:

package main

import (
    "fmt"
    "sync"
)

var (
    players sync.Map
)



func main(){
    //设置key对应的value
    players.Store("xiao ming",100)
    //返回key对应的valuee,value不存在时返回nil,false
    if value,ok:=players.Load("xiao ming");ok{
        fmt.Println(value)
    }else{
        fmt.Println("key:xiao ming does not exist!")
    }
    //如果key对应的value存在,则返回value和true
    //如果key对应的value不存在,则将key对应的value设置为参数中的value,并返回value和false
    if value,ok := players.LoadOrStore("xiao hong",120);ok{
        fmt.Println(value)
    }else{
        fmt.Println("key:xiao hong does not exist,store it!")
    }
    //遍历map,函数返回false时停止遍历
    players.Range(func(key,value interface{})bool{
        fmt.Println(key,value)
        return true
    })
    //删除key对应的value
    players.Delete("xiao hong")
}

atomic

sync.atomic提供了对几种简单类型进行原子操作的函数,相比Mutex/RWMutex,其性能更好,临界区也更小。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:土豆吞噬者

查看原文:Golang学习笔记-sync

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

600 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传