8.2 Go 锁
8.2 Go 锁
案例(坑):多个goroutine操作同一个map。
go提供了一种叫map的数据结构,可以翻译成映射,对应于其他语言的字典、哈希表。借助map,可以定义一个键和值,然后可以从map中获取、设置和删除这个值,尤其适合数据查找的场景。
但是map的使用有一定的限制,如果是在单个协程中读写map,那么不会存在什么问题,如果是多个协程并发访问一个map
,有可能会导致程序退出,并打印下面错误信息。
fatal error: concurrent map writes
错误案例代码
package main var myMap = make(map[int]int, 10) //要求计算50的阶乘结果
//阶乘就是1*2*3*4...50 =? func test(n int) {
//定义初始值1
res := 1
//每次循环进行阶乘
for i := 0; i <= n; i++ {
res *= i
}
//最终计算结果,写入map
//由于多个协程同时操作map,引发资源竞争报错
myMap[n] = res }
func main() {
//开启50个协程
for i := 0; i < 10; i++ {
go test(10)
}
}
并发访问map是不安全的操作,在协程
中访问map,必须提供某种同步资源
机制,使用sync.Mutex
互斥锁同步解决协程的竞争问题。
package main import (
"fmt"
"sync"
"time"
) var lock sync.Mutex func Printer(str string) {
//我现在开始使用打印机了,其他人都等我完事了再来
lock.Lock()
for _, data := range str {
fmt.Printf("%c", data)
time.Sleep(time.Second)
}
//我完事了,你们上吧
lock.Unlock()
fmt.Printf("\n")
} func Alex() {
Printer("hello")
}
func Wupeiqi() {
Printer("oldboy")
} func main() {
//coffe(10)//单线程执行函数
go Alex()
go Wupeiqi()
//主线程等待协程结束后 再退出
time.Sleep(time.Second * 10)
}
结论:
1.可以使用加锁的方式解决goroutine的通讯。
2.主线程等待所有goroutine的时间难以确定,设置固定的等待时间肯定不合理。
3.对全局变量加锁同步来通讯,也不利于多个协程对变量的读写。
4.要让主线程等待所有goroutine退出后在退出,如何知道所有goroutine都退出了呢?
5.因此,channel应运而生!!
8.2 Go 锁的更多相关文章
- 使用redis构建可靠分布式锁
关于分布式锁的概念,具体实现方式,直接参阅下面两个帖子,这里就不多介绍了. 分布式锁的多种实现方式 分布式锁总结 对于分布式锁的几种实现方式的优劣,这里再列举下 1. 数据库实现方式 优点:易理解 缺 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
- java中的锁
java中有哪些锁 这个问题在我看了一遍<java并发编程>后尽然无法回答,说明自己对于锁的概念了解的不够.于是再次翻看了一下书里的内容,突然有点打开脑门的感觉.看来确实是要学习的最好方式 ...
- 分布式锁1 Java常用技术方案
前言: 由于在平时的工作中,线上服务器是分布式多台部署的,经常会面临解决分布式场景下数据一致性的问题,那么就要利用分布式锁来解决这些问题.所以自己结合实际工作中的一些经验和网上看到的一些资 ...
- 如何在高并发环境下设计出无锁的数据库操作(Java版本)
一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...
- 如何定位Oracle数据库被锁阻塞会话的根源
首先再次明确下,数据库因为要同时保证数据的并发性和一致性,所以操作有锁等待是正常的. 只有那些长时间没有提交或回滚的事物,阻塞了其他业务正常操作,才是需要去定位处理的. 1.单实例环境 2.RAC环境 ...
- java 线程 Lock 锁使用Condition实现线程的等待(await)与通知(signal)
一.Condition 类 在前面我们学习与synchronized锁配合的线程等待(Object.wait)与线程通知(Object.notify),那么对于JDK1.5 的 java.util.c ...
- Android 死锁和重入锁
死锁的定义: 1.一般的死锁 一般的死锁是指多个线程的执行必须同时拥有多个资源,由于不同的线程需要的资源被不同的线程占用,最终导致僵持的状态,这就是一般死锁的定义. package com.cxt.t ...
- Xcode 锁终端
锁终端 输入: <1>cd /Applications/Xcode.app 回车 结果显示: Xcode.app 输入: <2>sudo chown -hR root:whee ...
- mysql 行级锁的使用以及死锁的预防
一.前言 mysql的InnoDB,支持事务和行级锁,可以使用行锁来处理用户提现等业务.使用mysql锁的时候有时候会出现死锁,要做好死锁的预防. 二.MySQL行级锁 行级锁又分共享锁和排他锁. 共 ...
随机推荐
- 2019-2020-1 20199308《Linux内核原理与分析》第一周作业
Linux 基础入门(新版)学习笔记 实验二 基本概念及操作 重要快捷键 Tab 补全命令 Ctrl+c 强行终止当前命令 历史命令 方向上键↑,恢复之前输入过的命令 通配符 在命令行中获取帮助 某个 ...
- Asp.Net Core 3.1学习-依赖注入、服务生命周期(6)
1.前言 面向对象设计(OOD)里有一个重要的思想就是依赖倒置原则(DIP),并由该原则牵引出依赖注入(DI).控制反转(IOC)及其容器等概念.在学习Core依赖注入.服务生命周期之前,下面让我们先 ...
- Hexo博客插入图片的方法
Hexo博客插入图片的方法 hexo图片blog hexo blog 插入图片的方法总结 hexo 的blog 内容是根据 markdown 文件的内容生成的html文件, 生成的文件全部在 /pub ...
- js之用IndexOf返回指定字符串的次数
代码 var Str = "strs,strs,stras,str,strs,strs"; var subStr ="strs" ; var count = 0 ...
- I/O多路复用之select,poll,epoll简介
一.select 1.起源 select最早于1983年出现在4.2BSD中(BSD是早期的UNIX版本的分支). 它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回 ...
- Shiro(二):Spring-boot如何集成Shiro(上)
这篇文章主要介绍了spring-boot是如何集成shiro的authentication流程的. 从shiro-spring-boot-web-starter说起 shiro-spring-boot ...
- php beast windows编译教程
git clone https://github.com/Microsoft/php-sdk-binary-tools.git c:\php-sdk cd c:\php-sdk git checkou ...
- P5960 差分约束算法模板
差分约束 差分约束,一般用来解决有\(n\)个未知数,\(m\)个不等式方程的问题,形如: \[\begin{cases} \ x_{a_1}-x_{b_1}\leq y_1\\ \ x_{a_2}- ...
- 一只简单的网络爬虫(基于linux C/C++)————socket相关及HTTP
socket相关 建立连接 网络通信中少不了socket,该爬虫没有使用现成的一些库,而是自己封装了socket的相关操作,因为爬虫属于客户端,建立套接字和发起连接都封装在build_connect中 ...
- .net core 基于Dapper 的分库分表开源框架(core-data)
一.前言 感觉很久没写文章了,最近也比较忙,写的相对比较少,抽空分享基于Dapper 的分库分表开源框架core-data的强大功能,更好的提高开发过程中的效率: 在数据库的数据日积月累的积累下,业务 ...