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行级锁 行级锁又分共享锁和排他锁. 共 ...
随机推荐
- 网络找的 关于 “中吹” Janus Dongye
看了这篇文章,感觉错过了一个精彩的人生. Janus Dongye, Coding Peasant at Universityof Cambridge (2012-present)(剑桥码农,2012 ...
- Github C 编译器项目 8cc main函数中用到的 C库函数
atexit C 库函数 int atexit(void (*func)(void)) 当程序正常终止时,调用指定的函数 func.您可以在任何地方注册你的终止函数,但它会在程序终止的时候被调用. s ...
- nginx 配置多个 https 域名访问
需要此操作的原因 在服务器上部署了 halo blog 以后,这次需要部署另外一个项目,但是又不想使用 ip + port,因此选择使用 nginx 配置多个域名访问. nginx 配置 server ...
- Spring Boot 之Spring data JPA简介
文章目录 添加依赖 添加entity bean 创建 Dao Spring Data Configuration 测试 Spring Boot 之Spring data JPA简介 JPA的全称是Ja ...
- PostgreSQL 10.0 preview 性能增强 - 分区表性能增强(plan阶段加速)
标签 PostgreSQL , 10.0 , 分区表 , 子表 , 元信息搜索性能增强 背景 PostgreSQL 10.0 增强了分区表的子表搜索性能,对于涉及分区表包含子表特别多的QUERY,可以 ...
- 提高Web服务器并发响应的经历
1 前言 ---------- 最近一直在维护一个线上运行的旧系统,系统本身的问题很多,然而又有大量客户准备试用.之前一直存有侥幸心理,希望系统能神奇的顶过这段时间,但这个蜗牛般的系统残忍的告诉我们- ...
- JVM调优:GC 参数
2019独角兽企业重金招聘Python工程师标准>>> JVM调优:GC 参数 博客分类: java jvm 参考: <Memory Management in the Jav ...
- Windows 怎么启动 apache
在可执行目录下找到httpd.exe命令,然后运行cmd,执行类似以下命令:C:\"Program Files"\"Apache Software Foundation& ...
- 最短路径树:Dijstra算法
一.背景 全文根据<算法-第四版>,Dijkstra算法.我们把问题抽象为2步:1.数据结构抽象 2.实现 二.算法分析 2.1 数据结构 顶点+边->图.注意:Dijkstra ...
- 软件——Jira是什么
JIRA这个工具接触有好几年了,在多个海外项目上都用过这个工具.去年又在项目上深度使用后就有点爱不释手了,回国后也在找机会推荐给其它项目上用.最近正好有新项目需要用,借这个机会把JIRA的配置学习的过 ...