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

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

  1. //多个线程同时运行,获得Mutex锁者线程优先执行,其余线程阻塞等待
  2. func testMutex() {
  3. mutex := sync.Mutex{};
  4. for i := ; i < ; i++ {
  5. go func(idx int) {
  6. mutex.Lock();
  7. defer mutex.Unlock();
  8. fmt.Println("idx :=", idx);
  9. time.Sleep(time.Second);
  10. }(i)
  11. }
  12.  
  13. time.Sleep( * time.Second);
  14. fmt.Println("Func finish.");
  15. }

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

  1. //写请求在读锁和写锁时都必须阻塞等待,读请求只在写锁时阻塞等待
  2. func testRWMutex() {
  3. rwMutex := sync.RWMutex{};
  4. for i := ; i < ; i++ {
  5. go func(idx int) {
  6. rwMutex.RLock();
  7. defer rwMutex.RUnlock();
  8. fmt.Println("Read Mutex :",idx);
  9. }(i);
  10.  
  11. go func(idx int) {
  12. rwMutex.Lock();
  13. defer rwMutex.Unlock();
  14. fmt.Println("Write Mutex :",idx);
  15. time.Sleep(time.Second);
  16. }(i);
  17. }
  18.  
  19. time.Sleep( * time.Second);
  20. fmt.Println("Func finish.");
  21. }

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

  1. func testCond() {
  2. cond := sync.NewCond(&sync.Mutex{});
  3.  
  4. cond.L.Lock(); //①上锁
  5. defer cond.L.Unlock();
  6.  
  7. go func() {
  8. fmt.Println("go wait lock.");
  9. cond.L.Lock(); //②等Wait解锁
  10.  
  11. defer cond.L.Unlock(); //⑤解锁后触发Wait
  12. defer fmt.Println("go unlock.");
  13.  
  14. fmt.Println("go locked.");
  15. cond.Signal(); //④触发Wait等待解锁
  16. }()
  17.  
  18. time.Sleep(time.Second);
  19.  
  20. fmt.Println("start wait.");
  21. for {
  22. cond.Wait(); //③可以理解为立刻解锁并触发一个阻塞线程(如果没有阻塞线程则不触发)后立刻再上锁等待Signal信号
  23. fmt.Println("wait finish.");
  24. break;
  25. }
  26.  
  27. time.Sleep(time.Second);
  28. fmt.Println("Func finish.");
  29. }

4.WaitGroup:组等待

  1. //Add 增加等待计数;Done减少等待计数;当计数为0时触发Wait;
  2. func testWaitGroup() {
  3. waitGroup := sync.WaitGroup{};
  4. for i := ; i < ; i++ {
  5. waitGroup.Add();
  6.  
  7. go func(idx int) {
  8. time.Sleep(time.Second);
  9. fmt.Println("go : ", idx);
  10. waitGroup.Done();
  11. }(i)
  12. }
  13.  
  14. for{
  15. fmt.Println("start wait.");
  16. waitGroup.Wait();
  17. fmt.Println("wait finish.");
  18. break;
  19. }
  20.  
  21. time.Sleep(time.Second);
  22. fmt.Println("Func finish.");
  23. }

5.Once:只执行一次

  1. //只执行一次以后不再触发
  2. func testOnce() {
  3. once := sync.Once{};
  4. for i := ; i < ; i++ {
  5. go func(idx int) {
  6. once.Do(func() {
  7. fmt.Println("Do once : ", idx); //这里只执行一次
  8. })
  9.  
  10. fmt.Println("go : ", idx);
  11. }(i)
  12. }
  13.  
  14. time.Sleep( * time.Second);
  15. fmt.Println("Func finish.");
  16. }

6.Map:线程安全map

  1. func testMap() {
  2. syncMap := sync.Map{};
  3. for i := ; i < ; i++ {
  4. go func(idx int) {
  5. //如果没有则保存起来
  6. _, ok := syncMap.LoadOrStore(idx, " StrVal = "+strconv.FormatInt(int64(idx), ));
  7. if !ok {
  8. fmt.Println("Store idx = ",idx);
  9. }
  10. }(i)
  11.  
  12. go func(idx int) {
  13. val, ok := syncMap.Load(idx);
  14. if ok {
  15. fmt.Println("Load success idx = ", idx, val);
  16. } else {
  17. fmt.Println("Load fail idx = ", idx)
  18. }
  19. }(i)
  20.  
  21. }
  22.  
  23. time.Sleep( * time.Second);
  24. fmt.Println("Func finish.");
  25. }

7.Pool:线程安全对象池

  1. func testPool() {
  2. p := &sync.Pool{
  3. New: func() interface{} {
  4. return -;
  5. },
  6. }
  7.  
  8. for i := ; i < ; i++ {
  9. go func(idx int) {
  10. p.Put(idx);
  11. }(i)
  12. }
  13.  
  14. //取出来的对象是无序的
  15. for i := ; i < ; i++ {
  16. go func() {
  17. val := p.Get();
  18. fmt.Println("Get val = ", val);
  19. }()
  20. }
  21.  
  22. time.Sleep( * time.Second);
  23. fmt.Println("Func finish.");
  24. }

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

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

2.GC会将Pool清理掉。

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

  1. func testPoolPutGet(){
  2. myPool := &sync.Pool{
  3. New: func() interface{} {
  4. return ;
  5. },
  6. }
  7.  
  8. myPool.Put() //放入1
  9. myPool.Put() //放入2
  10.  
  11. time.Sleep(time.Second)
  12.  
  13. p1 := myPool.Get().(int)
  14. fmt.Println(p1) // 获得2
  15.  
  16. p2 := myPool.Get().(int)
  17. fmt.Println(p2) // 获得0,而不是1!
  18. }

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. bzoj4720 / P1850 换教室(Floyd+期望dp)

    P1850 换教室 先用Floyd把最短路处理一遍,接下来就是重头戏了 用 f [ i ][ j ][ 0/1 ] 表示在第 i 个时间段,发出了 j 次申请(注意不一定成功),并且在这个时间段是否( ...

  2. Linux UinxODBC安装与配置

    Linux UinxODBC安装与配置 一.简介 ODBC是Open Database Connect 即开发数据库互连的简称,它是一个用于访问数据库的统一界面标准.ODBC引入一个公共接口以解决不同 ...

  3. ssh-keygen 命令

    功能 生成.管理和转换认证密钥,包括 RSA 和 DSA 两种密钥,密钥类型可以用 -t 选项指定.如果没有指定则默认生成用于SSH-2的RSA密钥,系统管理员还可以用它产生主机密钥. 通常,这个程序 ...

  4. XXX银行项目部署

    XXX银行项目部署 一.下载项目代码 1.使用git工具下载代码 代码路径:推荐代码下载到桌面 git clone http://sunyard_姓名拼音@bitbucket.devops.hfdev ...

  5. python简说(十八)导入模块

    1.import xx import 一个模块的实质就是把这个python文件从头到尾执行一遍 2.import模块的查找模块的顺序 1).从当前目录下找 2).sys.path python的安装目 ...

  6. 你不知道的JavaScript(1)LHS查询和RHS查询

    打算把<你不知道的JavaScript>中的知识点整理下,写点自己的心得,同时也敦促自己看书. 先做个整体的介绍,最后会再给个综合的例子. RHS 查询与简单地查找某个变量的值别无二致,而 ...

  7. python --- 20 约束 异常处理 MD5 日志

    一.类的约束 1.抛出异常    NotImplementedError 2.抽象方法 含有抽象方法的类是抽象类 抽象类中的方法全是抽象方法的是接口 抽象类不能创建对象 二.异常处理 处理完后代码可继 ...

  8. Class DesiredCapabilities

    public class DesiredCapabilities extends java.lang.Object implements java.io.Serializable, Capabilit ...

  9. uniGUI试用笔记(七)

    uniGUI的文件下载由于TUniSession的存在而变得非常简单,最典型的一个例子就是将列表中的所有数据导出到Excel中.服务器上采用TMS FlexCel控件,先将数据集中的记录导入到Exce ...

  10. 【Hadoop 分布式部署 一 :分布式部署准备虚拟机 】

    一.将IP配置为静态 按照 下面的操作将IP配置为静态IP  这个静态的IP地址 是你自己设置的,只要符合虚拟机的IP段就可以.最后点击 Apply  需要root密码 将网络断开 (在网络图标左键  ...