Go1.9.2 sync库里包含下面几类:Mutex/RWMutex/Cond/WaitGroup/Once/Map/Pool

1.Mutex:互斥锁,等同于linux下的pthread_mutex_t

//多个线程同时运行,获得Mutex锁者线程优先执行,其余线程阻塞等待
func testMutex() {
mutex := sync.Mutex{};
for i := ; i < ; i++ {
go func(idx int) {
mutex.Lock();
defer mutex.Unlock();
fmt.Println("idx :=", idx);
time.Sleep(time.Second);
}(i)
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}

2.RWMutex:读写锁,等同于linux下的pthread_rwlock_t

//写请求在读锁和写锁时都必须阻塞等待,读请求只在写锁时阻塞等待
func testRWMutex() {
rwMutex := sync.RWMutex{};
for i := ; i < ; i++ {
go func(idx int) {
rwMutex.RLock();
defer rwMutex.RUnlock();
fmt.Println("Read Mutex :",idx);
}(i); go func(idx int) {
rwMutex.Lock();
defer rwMutex.Unlock();
fmt.Println("Write Mutex :",idx);
time.Sleep(time.Second);
}(i);
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}

3.Cond:条件变量,等同于linux下的pthread_cond_t

func testCond() {
cond := sync.NewCond(&sync.Mutex{}); cond.L.Lock(); //①上锁
defer cond.L.Unlock(); go func() {
fmt.Println("go wait lock.");
cond.L.Lock(); //②等Wait解锁 defer cond.L.Unlock(); //⑤解锁后触发Wait
defer fmt.Println("go unlock."); fmt.Println("go locked.");
cond.Signal(); //④触发Wait等待解锁
}() time.Sleep(time.Second); fmt.Println("start wait.");
for {
cond.Wait(); //③可以理解为立刻解锁并触发一个阻塞线程(如果没有阻塞线程则不触发)后立刻再上锁等待Signal信号
fmt.Println("wait finish.");
break;
} time.Sleep(time.Second);
fmt.Println("Func finish.");
}

4.WaitGroup:组等待

//Add 增加等待计数;Done减少等待计数;当计数为0时触发Wait;
func testWaitGroup() {
waitGroup := sync.WaitGroup{};
for i := ; i < ; i++ {
waitGroup.Add(); go func(idx int) {
time.Sleep(time.Second);
fmt.Println("go : ", idx);
waitGroup.Done();
}(i)
} for{
fmt.Println("start wait.");
waitGroup.Wait();
fmt.Println("wait finish.");
break;
} time.Sleep(time.Second);
fmt.Println("Func finish.");
}

5.Once:只执行一次

//只执行一次以后不再触发
func testOnce() {
once := sync.Once{};
for i := ; i < ; i++ {
go func(idx int) {
once.Do(func() {
fmt.Println("Do once : ", idx); //这里只执行一次
}) fmt.Println("go : ", idx);
}(i)
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}

6.Map:线程安全map

func testMap() {
syncMap := sync.Map{};
for i := ; i < ; i++ {
go func(idx int) {
//如果没有则保存起来
_, ok := syncMap.LoadOrStore(idx, " StrVal = "+strconv.FormatInt(int64(idx), ));
if !ok {
fmt.Println("Store idx = ",idx);
}
}(i) go func(idx int) {
val, ok := syncMap.Load(idx);
if ok {
fmt.Println("Load success idx = ", idx, val);
} else {
fmt.Println("Load fail idx = ", idx)
}
}(i) } time.Sleep( * time.Second);
fmt.Println("Func finish.");
}

7.Pool:线程安全对象池

func testPool() {
p := &sync.Pool{
New: func() interface{} {
return -;
},
} for i := ; i < ; i++ {
go func(idx int) {
p.Put(idx);
}(i)
} //取出来的对象是无序的
for i := ; i < ; i++ {
go func() {
val := p.Get();
fmt.Println("Get val = ", val);
}()
} time.Sleep( * time.Second);
fmt.Println("Func finish.");
}

使用Pool一定要注意一下问题:

1.用途仅仅是增加对象重用的几率,减少gc的负担,而开销方面也不是很便宜的。

2.GC会将Pool清理掉。

3.Get不能保证将Put进去的全部取出来!如下例子:

func testPoolPutGet(){
myPool := &sync.Pool{
New: func() interface{} {
return ;
},
} myPool.Put() //放入1
myPool.Put() //放入2 time.Sleep(time.Second) p1 := myPool.Get().(int)
fmt.Println(p1) // 获得2 p2 := myPool.Get().(int)
fmt.Println(p2) // 获得0,而不是1!
}

4.关于Pool的实现原理,可以参考《go语言的官方包sync.Pool的实现原理和适用场景》

以上。

Golang sync的更多相关文章

  1. Golang Sync.WaitGroup 使用及原理

    Golang Sync.WaitGroup 使用及原理 使用 func main() { var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.A ...

  2. golang sync/atomic

    刚刚学习golang原子操作处理的时候发现github上面一个比较不错的golang学习项目 附上链接:https://github.com/polaris1119/The-Golang-Standa ...

  3. Golang:sync.Map

    由于map在gorountine 上不是安全的,所以在大量并发读写的时候,会出现错误. 在1.9版的时候golang推出了sync.Map. sync.Map 通过阅读源码我们发现sync.Map是通 ...

  4. golang sync包

    sync 在golang 文档上,golang不希望通过共享内存来进行进程间的协同操作,而是通过channel的方式来进行,当然,golang也提供了共享内存,锁等机制进行协同操作的包: 互斥锁: M ...

  5. golang sync.noCopy 类型 —— 初探 copylocks 与 empty struct

    问题引入 学习golang(v1.16)的 WaitGroup 代码时,看到了一处奇怪的用法,见下方类型定义: type WaitGroup struct { noCopy noCopy ... } ...

  6. golang sync.Cond条件变量的使用

    cond.Wait()的操作实际上是对与cond绑定的锁先进行解锁,在等待通知:接收到通知后,会尝试加锁,加锁成功则唤醒否则继续等待通知: cond.Waite()前必须对关连锁加锁,否则panic ...

  7. golang sync.Pool包的使用和一些注意地方

    package main; import ( "sync" "fmt" "net" "runtime" ) //sync ...

  8. golang sync.Cond 类

    众所周知,go语言在多线程方面的支持是十分完备的.在go语言sync包中提供了一个Cond类,这个类用于goroutine之间进行协作. 这个类并不复杂,只有三个函数,Broadcast() , Si ...

  9. golang sync.RWMutex

    sync.RWMutex package main import ( "fmt" "runtime" "sync" ) func click ...

随机推荐

  1. Python3 join函数和os.path.join用法

    Python3  join函数和os.path.join用法 os.path.join()连接两个文件名地址的时候,就比os.path.join("D:\","test. ...

  2. javascript 点击按钮实现隐藏显示切换效果

    原文链接:http://www.jb51.net/article/79083.htm <html> <head> <meta charset="gb2312&q ...

  3. Bugku-CTF之web3-flag就在这里快来找找吧

    Day6 web3 30 flag就在这里快来找找吧http://123.206.87.240:8002/web3/ 本题要点:NCR 转义序列(Unicode)   在Windows中经常需要用到多 ...

  4. Codeforces 844D Interactive LowerBound - 随机化

    This is an interactive problem. You are given a sorted in increasing order singly linked list. You s ...

  5. Selenium Java Selection的使用

    用于向具有drop-down的选择框中输入内容 new Select(new ChromeDriver().findElement(By.cssSelector(" ..."))) ...

  6. Python3 tkinter基础 Button text,fg 按钮上显示的文字 文字的颜色

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  7. R语言 格式化数字

    x = 1111111234.6547389758965789345 y = formatC(x, digits = 8, format = "f") # [1] "11 ...

  8. asp.net mvc 加三层架构 完美搭配

    http://www.hysql.org/aspnet/20180630/5712.html 先来一张项目的层级结构图: Model:模型层,主要是各种类型.枚举以及ORM框架,框架完成数据库和实体类 ...

  9. 物体检测算法 SSD 的训练和测试

    物体检测算法 SSD 的训练和测试 GitHub:https://github.com/stoneyang/caffe_ssd Paper: https://arxiv.org/abs/1512.02 ...

  10. [JavaScript] - 判断时间是否是当天

    https://www.codewars.com/kata/is-the-date-today/train/javascript function isToday(date) { return new ...