登录
首页 >  Golang >  Go教程

GoLang切片并发安全解决方案详解

来源:脚本之家

时间:2022-12-22 16:55:29 130浏览 收藏

在Golang实战开发的过程中,我们经常会遇到一些这样那样的问题,然后要卡好半天,等问题解决了才发现原来一些细节知识点还是没有掌握好。今天golang学习网就整理分享《GoLang切片并发安全解决方案详解》,聊聊Lang切片、并发安全,希望可以帮助到正在努力赚钱的你。

1.介绍切片并发问题

关于切片的,Go语言中的切片原生支持并发吗?

2.实践检验真理

实践是检验真理的唯一标准,所以当我们遇到一个不确定的问题,直接写demo来验证,因为切片的特点,我们可以分多种情况来验证

1.不指定索引,动态扩容并发向切片添加数据

2.指定索引,指定容量并发向切片添加数据

  • 不指定索引,动态扩容并发向切片添加数据

不指定索引,动态扩容并发向切片添加数据:

通过打印数据发现每次len与cap的结果都不一致

func concurrentAppendSliceNotForceIndex() {
	sl := make([]int, 0)
	wg := sync.WaitGroup{}
	for index := 0; index 
  • 指定索引,指定容量并发向切片添加数据

指定索引,指定容量并发向切片添加数据:

通过结果我们可以发现符合我们的预期,长度和容量都是100

func concurrentAppendSliceForceIndex() {
	sl := make([]int, 100)
	wg := sync.WaitGroup{}
	for index := 0; index 

3.回答切片并发安全问题

我们都知道切片是对数组的抽象,其底层就是数组,在并发下写数据到相同的索引位会被覆盖,并且切片也有自动扩容的功能,当切片要进行扩容时,就要替换底层的数组,在切换底层数组时,多个goroutine是同时运行的,哪个goroutine先运行是不确定的,不论哪个goroutine先写入内存,肯定就有一次写入会覆盖之前的写入,所以在动态扩容时并发写入数组是不安全的;

所以当别人问你slice支持并发时,你就可以这样回答它:

当指定索引使用切片时,切片是支持并发读写索引区的数据的,但是索引区的数据在并发时会被覆盖的;当不指定索引切片时,并且切片动态扩容时,并发场景下扩容会被覆盖,所以切片是不支持并发的~。

4.解决切片并发安全问题方式

针对上述问题,我们可以多种方法来解决切片并发安全的问题:

1.加互斥锁

2.使用channel串行化操作

3.使用sync.map代替切片

5.附

设置为1的的时候,runtime.GOMAXPROCS(1)

package main
import (
	"fmt"
	"runtime"
	"sync"
)
func concurrentAppendSliceNotForceIndex() {
	sl := make([]int, 0)
	wg := sync.WaitGroup{}
	for index := 0; index 
package main
import (
	"fmt"
	"runtime"
	"sync"
)
var wg sync.WaitGroup
var sl []int
func add() {
	for index := 0; index 
package main
import (
	"fmt"
	"runtime"
	"sync"
)
var wg sync.WaitGroup
var sl []int
func add() {
	for index := 0; index 

不限数量:

package main
import (
	"fmt"
	"sync"
)
var wg sync.WaitGroup
var sl []int
func add() {
	for index := 0; index 

加锁

package main
import (
	"fmt"
	"sync"
)
var wg sync.WaitGroup
var sl []int
var lock sync.Mutex
func add() {
	for index := 0; index 

到这里,我们也就讲完了《GoLang切片并发安全解决方案详解》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于golang的知识点!

声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>