我们先假设一个需求,创建一个数组,里面存放 0 - 99 的整数。

上代码:

输出:

然而并不是我们想要的结果,很多重复数值。

释义:

12行这个闭包函数对 i 的传递并非深拷贝,而是传递了变量指针,也就意味着多个协程访问的时候操作的是同一块内存。

当某一个协程修改了i的值,导致多个协程append的时候i的值发生变化,简单的说就是一个更改,多个读取同时存在,很多个协程都读到某个数值,比如是14,多个协程执行后大家的结果都是一样,是15.

我们升级下代码:

输出:

我们可以看到第2行的输出94,如果没有多运行几次,少于100,也就是说发生了数据丢失,这是为何?

这就是竞态,因为多个协程同时访问临界区,程序并不是按照先后顺序去执行,多个协程抢占资源,这就导致一部分协程没有得到资源。

解决的办法很多,这里讲解下互斥锁和更换数据类型

办法1:换数据类型

切片不同于数组,在每次append的时候我们会伴随着内存copy以达到自动扩容目的,在A协程读出a的内存数据时,B协程完成了写入操作,此时A继续append并赋值就会导致,协程B的更新结果丢失。
假如我们将切片换成数组就不存在这个问题:

稳定输出:

2:互斥锁

输出元素的次序没有规律,但是个数很稳定:

也就是说没有丢失数据

Go 初体验 - 闭包,数组,切片,锁的更多相关文章

  1. Go语言学习之4 递归&闭包&数组切片&map&锁

    主要内容: 1. 内置函数.递归函数.闭包2. 数组与切片3. map数据结构4. package介绍 5. 排序相关 1. 内置函数.递归函数.闭包 1)内置函数 (1). close:主要用来关闭 ...

  2. go:内置函数 | 闭包 | 数组 | 切片 | 排序 | map | 锁

    内置函数 1.close: 主要是用来关闭channel 2.len:用来求长度,比如string.array.slice.map.channel 3.new与make都是用来分配内存 new用来分配 ...

  3. Go 初体验 - 闭包的几种情况

    闭包: 闭包是可以包含自由(未绑定到特定对象)变量的代码块,这些变量不在这个代码块内或者任何全局上下文中定义,而是在定义代码块的环境中定义.要执行的代码块(由于自由变量包含在代码块中,所以这些自由变量 ...

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

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

  5. 数据结构(逻辑结构,物理结构,特点) C#多线程编程的同步也线程安全 C#多线程编程笔记 String 与 StringBuilder (StringBuffer) 数据结构与算法-初体验(极客专栏)

    数据结构(逻辑结构,物理结构,特点) 一.数据的逻辑结构:指反映数据元素之间的逻辑关系的数据结构,其中的逻辑关系是指数据元素之间的前后件关系,而与他们在计算机中的存储位置无关.逻辑结构包括: 集合 数 ...

  6. Node.js 网页瘸腿爬虫初体验

    延续上一篇,想把自己博客的文档标题利用Node.js的request全提取出来,于是有了下面的初哥爬虫,水平有限,这只爬虫目前还有点瘸腿,请看官你指正了. // 内置http模块,提供了http服务器 ...

  7. go语言的初体验

    分享最近学习 Go 语言的心得和体会,适合有编程基础的人,因为这里只做经验性的总结概述,不做基础教学的入门知识讲解,如果想要学习编程语言的基础知识,请出门左转进入官方文档,查看基础教学文档. Go 概 ...

  8. Java高级特性1_流库_初体验

    Java高级特性流库_初体验 面对结果编程 在编程里, 有两种编程方式, 一种是面对过程编程, 一种是面对结果编程. 两者区别如下 面向过程编程 面向过程编程需要编程程序让程序依次执行得到自己想要的结 ...

  9. .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验

    不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...

随机推荐

  1. C# - 获取windows系统特殊文件夹路径

    一.路径分类 1.绝对路径 完整路径,从磁盘符号开始,如:C:\Windows 2.相对路径 以当前路径为起点,不包含磁盘符号,通常使用“..\”符号来访问上级目录中的文件或文件夹. ../Windo ...

  2. org.hibernate.exception.SQLGrammarException: could not extract ResultSet &&&&&Incorrect syntax near '@P0'.

    这个故障的原因比较多: 1.如数据库中的字段和类中的字段类型不一致: 2.数据库dialect不够具体 myeclispe自动生成的是  org.hibernate.dialect.SQLServer ...

  3. js函数声明和函数表达式的区别

    Javascript Function无处不在,而且功能强大!通过Javascript函数可以让JS具有面向对象的一些特征,实现封装.继承等,也可以让代码得到复用.但事物都有两面性,Javascrip ...

  4. larave异步多图片上传的实现和注意事项及$file的对象函数

    要使用多图片上传,首先要在input添加multipart,同时注意name的参数要加[],不然,不算是数组.具体如下,注意绿色地方.如果是单张图片,把[]去掉,不要multiple; <inp ...

  5. python在读取文件时出现 'gbk' codec can't decode byte 0x89 in position 68: illegal multibyte sequence

    python在读取文件时出现“UnicodeDecodeError:'gbk' codec can't decode byte 0x89 in position 68: illegal multiby ...

  6. SQL - 1.区分login、user、schema和role

        Login Login 是Server一级的概念,表示登录Server的凭证,比如在Server_A上有一个数据库DA,那么想要访问数据库DA,第一步要做的事情就是先登录到Hosting该数据 ...

  7. 如何将WORD表格转换成EXCEL表格

    WORD和EXCEL都可以制作表格,但WORD表格与EXCEL表格之间有着很明显的差距,所以在办公中经常会需要将WORD转换成EXCEL,今天小编就教大家一招将WORD表格转换成EXCEL表格. 操作 ...

  8. SpringBoot注解大全 转

    2019年3月17日22:30:10 一.注解(annotations)列表 @SpringBootApplication:包含了@ComponentScan.@Configuration和@Enab ...

  9. C语言:二进制模5

    输入一串字符,若是二进制则求其模五的值. 要求:1.若输入的字符包含除0.1以外的值,则输出:invalid 2.若输入的为二进制字符串,则输出所计算的其模五的值 3.若其输入字符均为0.1,但是第一 ...

  10. python to shell vimdiff

    目录 #!/bin/python3 import os import sys if(len(sys.argv) != 3): exit ("Usage: argv1:fullPath.txt ...