竞态,就是多个协程同时访问临界区,由并发而产生的数据不同步的状态。

这个说的有点low,没办法,我就是这么表达的,官方的请度娘。

先上代码:

输出:

为何不是1000?就是因为竞态,发生竞态后,最终的输出是以最后一个协程执行的结果为准,但最后一个协程有一定的随机性,不是先跑先完。

改一下代码:

输出:

因为加了锁,这1000个协程是按照队列的顺序执行12行,所以稳定输出 final value of x 1000

再看:

输出:

照样稳定输出 final value of x 1000,因为信道的读和写都具有排他性,虽然不是锁住临界区,但是能起到让后来的协程排队的效果。

那么这两种情况怎么选择呢? 引用一个大牛的话:

Mutex vs 信道

通过使用 Mutex 和信道,我们已经解决了竞态条件的问题。那么我们该选择使用哪一个?答案取决于你想要解决的问题。如果你想要解决的问题更适用于 Mutex,那么就用 Mutex。如果需要使用 Mutex,无须犹豫。而如果该问题更适用于信道,那就使用信道。:)

由于信道是 Go 语言很酷的特性,大多数 Go 新手处理每个并发问题时,使用的都是信道。这是不对的。Go 给了你选择 Mutex 和信道的余地,选择其中之一都可以是正确的。

总体说来,当 Go 协程需要与其他协程通信时,可以使用信道。而当只允许一个协程访问临界区时,可以使用 Mutex。

就我们上面解决的问题而言,我更倾向于使用 Mutex,因为该问题并不需要协程间的通信。所以 Mutex 是很自然的选择。

我的建议是去选择针对问题的工具,而别让问题去将就工具。:)

Go 初体验 - 并发与锁.3 - 竞态的更多相关文章

  1. Go 初体验 - 并发与锁.1 - sync.Mutex 与 sync.RWMutex

    ==== Mutex为互斥锁,顾名思义,被Mutex锁住的代码同时只允许一个协程访问,其它协程进来就要排队 如何使用?看代码: 输出: 释义: 并发1000个协程同时更改m的元素,这样会有一部分更改成 ...

  2. Go 初体验 - 并发与锁.2 - sync.WaitGroup

    sync包里的WaitGroup主要用于协程同步 计数主协程创建的子线程 WaitGoup.Add(i) 调用清除标记方法WaitGroup.Done() 使用WaitGroup.Wait()来阻塞, ...

  3. 学习Go语言之使用原子访问或互斥锁解决竞态问题

    使用原子访问或互斥锁 // 解决竞态问题 package main import ( "fmt" "sync" "sync/atomic" ...

  4. Swift初体验之图案锁

    这篇在应用上貌似没有价值,貌似我写了好多实际上都没有价值,这里贴出来就是分享下. 自己写swift好多天了,感觉好多东西还是不太懂,边学边做,互勉! 先上图: 代码:下载

  5. Java并发之多线程下竞态条件概念的理解

    一.简述 竞态条件(Race Condition):计算的正确性取决于多个线程的交替执行时序时,就会发生竞态条件. 二.常见竞态条件分析 最常见的竞态条件为 1.先检测后执行 执行依赖于检测的结果,而 ...

  6. Scala 深入浅出实战经典 第66讲:Scala并发编程实战初体验

    王家林亲授<DT大数据梦工厂>大数据实战视频 Scala 深入浅出实战经典(1-87讲)完整视频.PPT.代码下载:百度云盘:http://pan.baidu.com/s/1c0noOt6 ...

  7. 高性能无锁队列 Disruptor 初体验

    原文地址: haifeiWu和他朋友们的博客 博客地址:www.hchstudio.cn 欢迎转载,转载请注明作者及出处,谢谢! 最近一直在研究队列的一些问题,今天楼主要分享一个高性能的队列 Disr ...

  8. 并发王者课 - 青铜4:synchronized用法初体验

    在前面的文章<双刃剑-理解多线程带来的安全问题>中,我们提到了多线程情况下存在的线程安全问题.本文将以这个问题为背景,介绍如何通过使用synchronized关键字解这一问题.当然,在青铜 ...

  9. 漫画|Linux 并发、竞态、互斥锁、自旋锁、信号量都是什么鬼?(转)

    知乎链接:https://zhuanlan.zhihu.com/p/57354304 1. 锁的由来? 学习linux的时候,肯定会遇到各种和锁相关的知识,有时候自己学好了一点,感觉半桶水的自己已经可 ...

随机推荐

  1. H5测试与PC端测试不同的点

    1.通过H5网页(非手机的返回功能)的返回功能可以返回,不会出现无法返回的情况. 2.横屏竖屏相互切换,能自适应,并且布局不会乱掉: 3.为能在不同分辨率的手机上能更好的展示,建议采用响应式设计(如: ...

  2. Cow Relays POJ - 3613 (floyd+快速幂)

    For their physical fitness program, N (2 ≤ N ≤ 1,000,000) cows have decided to run a relay race usin ...

  3. C#-导入Excel 内容到 DataTable中

    C#-导入Excel 内容到 DataTable中 直接传入文件路径,支持所有Excel格式. 缺点:如果数据量庞大会很占内存. public static DataTable ImportExcel ...

  4. angularJs实现数据双向绑定的原理

    angular1.x在指定的事件触发时(比如dom事件,xhr响应事件,浏览器定位变更事件,定时器事件),通过脏值检测的方式比对数据是否有变更,来决定是否更新视图. angular2使用了zone.j ...

  5. Django聚合分组查询、常用字段

    首先回顾sql中聚合和分组的概念: 如果没有分组,会把整张表作为一个大组,查询字段必须是聚合结果:如果有分组,分组之后,必须要使用聚合的结果作为having的条件. 聚合查询 聚合:aggregate ...

  6. 查看百度CUID方法

    百度地图CUID号获取方法:安卓系统百度地图APP→“设置”→ 长按“关于”

  7. Lock锁方式解决线程安全问题

    在JDK5.0之后新增加了一种更强大的线程同步机制---通过显示定义同步锁来实现线程同步解决线程安全问题.同步锁使用Lock对象充当. java.util.concurrent.locks.lock接 ...

  8. 六、web应用与Tomcat

    软件系统体系结构 1 常见软件系统体系结构B/S.C/S 1.1 C/S l C/S结构即客户端/服务器(Client/Server),例如QQ: l 需要编写服务器端程序,以及客户端程序,例如我们安 ...

  9. 中文乱码总结之web乱码情景

    情景1.当servlet返回js脚本时弹出框显示中文乱码: 解决:在servlet中加上response.setContentType(“text/html;charset=utf-8”); 情景2. ...

  10. 熟悉Linux常用命令

    cd命令:切换目录 (1)切换到目录 /usr/localcd / usrcd / local (2)去到目前的上层目录cd .. (3)回到自己的主文件夹cd ls命令:查看文件与目录 (4)查看目 ...