版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第GoLang切片并發(fā)安全解決方案詳解目錄1.介紹切片并發(fā)問(wèn)題2.實(shí)踐檢驗(yàn)真理3.回答切片并發(fā)安全問(wèn)題4.解決切片并發(fā)安全問(wèn)題方式5.附
1.介紹切片并發(fā)問(wèn)題
關(guān)于切片的,Go語(yǔ)言中的切片原生支持并發(fā)嗎?
2.實(shí)踐檢驗(yàn)真理
實(shí)踐是檢驗(yàn)真理的唯一標(biāo)準(zhǔn),所以當(dāng)我們遇到一個(gè)不確定的問(wèn)題,直接寫(xiě)demo來(lái)驗(yàn)證,因?yàn)榍衅奶攸c(diǎn),我們可以分多種情況來(lái)驗(yàn)證
1.不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù)
2.指定索引,指定容量并發(fā)向切片添加數(shù)據(jù)
不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù)
不指定索引,動(dòng)態(tài)擴(kuò)容并發(fā)向切片添加數(shù)據(jù):
通過(guò)打印數(shù)據(jù)發(fā)現(xiàn)每次len與cap的結(jié)果都不一致
funcconcurrentAppendSliceNotForceIndex(){
sl:=make([]int,0)
wg:=sync.WaitGroup{}
forindex:=0;index100;index++{
k:=index
wg.Add(1)
gofunc(numint){
sl=append(sl,num)
wg.Done()
}(k)
wg.Wait()
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
funcmain(){
concurrentAppendSliceNotForceIndex()
/*第一次運(yùn)行代碼后,輸出:[2015678910417111213141516211819202322242526392728293031355554565758596061626463656667686970717273747576777879808182838486919293949695979899]
finallen(sl)=74cap(sl)=128*/
//第二次運(yùn)行代碼后,輸出:省略切片元素輸出...finallen(sl)=81cap(sl)=128
//第二次運(yùn)行代碼后,輸出:省略切片元素輸出...finallen(sl)=77cap(sl)=128
}
指定索引,指定容量并發(fā)向切片添加數(shù)據(jù)
指定索引,指定容量并發(fā)向切片添加數(shù)據(jù):
通過(guò)結(jié)果我們可以發(fā)現(xiàn)符合我們的預(yù)期,長(zhǎng)度和容量都是100
funcconcurrentAppendSliceForceIndex(){
sl:=make([]int,100)
wg:=sync.WaitGroup{}
forindex:=0;index100;index++{
k:=index
wg.Add(1)
gofunc(numint){
sl[num]=num
wg.Done()
}(k)
wg.Wait()
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
funcmain(){
concurrentAppendSliceForceIndex()
/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787
98081828384858687888990919293949596979899]
finallen(sl)=100cap(sl)=100*/
/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787
98081828384858687888990919293949596979899]
finallen(sl)=100cap(sl)=100*/
/*第一次運(yùn)行代碼后,輸出:[01234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787
98081828384858687888990919293949596979899]
finallen(sl)=100cap(sl)=100*/
3.回答切片并發(fā)安全問(wèn)題
我們都知道切片是對(duì)數(shù)組的抽象,其底層就是數(shù)組,在并發(fā)下寫(xiě)數(shù)據(jù)到相同的索引位會(huì)被覆蓋,并且切片也有自動(dòng)擴(kuò)容的功能,當(dāng)切片要進(jìn)行擴(kuò)容時(shí),就要替換底層的數(shù)組,在切換底層數(shù)組時(shí),多個(gè)goroutine是同時(shí)運(yùn)行的,哪個(gè)goroutine先運(yùn)行是不確定的,不論哪個(gè)goroutine先寫(xiě)入內(nèi)存,肯定就有一次寫(xiě)入會(huì)覆蓋之前的寫(xiě)入,所以在動(dòng)態(tài)擴(kuò)容時(shí)并發(fā)寫(xiě)入數(shù)組是不安全的;
所以當(dāng)別人問(wèn)你slice支持并發(fā)時(shí),你就可以這樣回答它:
當(dāng)指定索引使用切片時(shí),切片是支持并發(fā)讀寫(xiě)索引區(qū)的數(shù)據(jù)的,但是索引區(qū)的數(shù)據(jù)在并發(fā)時(shí)會(huì)被覆蓋的;當(dāng)不指定索引切片時(shí),并且切片動(dòng)態(tài)擴(kuò)容時(shí),并發(fā)場(chǎng)景下擴(kuò)容會(huì)被覆蓋,所以切片是不支持并發(fā)的~。
4.解決切片并發(fā)安全問(wèn)題方式
針對(duì)上述問(wèn)題,我們可以多種方法來(lái)解決切片并發(fā)安全的問(wèn)題:
1.加互斥鎖
2.使用channel串行化操作
3.使用sync.map代替切片
5.附
設(shè)置為1的的時(shí)候,runtime.GOMAXPROCS(1)
packagemain
import(
"fmt"
"runtime"
"sync"
funcconcurrentAppendSliceNotForceIndex(){
sl:=make([]int,0)
wg:=sync.WaitGroup{}
forindex:=0;index100;index++{
k:=index
wg.Add(1)
gofunc(numint){
sl=append(sl,num)
wg.Done()
}(k)
wg.Wait()
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
funcmain(){
runtime.GOMAXPROCS(1)
concurrentAppendSliceNotForceIndex()
[99012345678910111213141516171819202122232425262728
29303132333435363738394041424344454647484950515253545
55657585960616263646566676869707172737475767778798081
8283848586878889909192939495969798]
finallen(sl)=100cap(sl)=128
[13012345678910111299141516171819202122232425262728
29303132333435363738394041424344454647484950515253545
55657585960616263646566676869707172737475767778798081
8283848586878889909192939495969798]
finallen(sl)=100cap(sl)=128
[10012345678999111213141516171819202122232425262728
29303132333435363738394041424344454647484950515253545
55657585960616263646566676869707172737475767778798081
8283848586878889909192939495969798]
finallen(sl)=100cap(sl)=128
packagemain
import(
"fmt"
"runtime"
"sync"
varwgsync.WaitGroup
varsl[]int
funcadd(){
forindex:=0;index100;index++{
sl=append(sl,index)
wg.Done()
funcmain(){
runtime.GOMAXPROCS(1)
wg.Add(1)
goadd()
wg.Wait()
//無(wú)論執(zhí)行多少次都輸出一下結(jié)果
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
[012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626
3646566676869707172737475767778798081828384858687888990919293949596979899]
finallen(sl)=100cap(sl)=128
}
packagemain
import(
"fmt"
"runtime"
"sync"
varwgsync.WaitGroup
varsl[]int
funcadd(){
forindex:=0;indexindex++{
sl=append(sl,index)
wg.Done()
funcmain(){
runtime.GOMAXPROCS(1)
wg.Add(2)
goadd()
goadd()
wg.Wait()
//無(wú)論執(zhí)行多少次都輸出一下結(jié)果
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
[012345678910111213141516171819202122232425262728293031323334353637383940414243444546474849012345678910111213141516
171819202122232425262728293031323334353637383940414243444546474849]
finallen(sl)=100cap(sl)=128
}
不限數(shù)量:
packagemain
import(
"fmt"
"sync"
varwgsync.WaitGroup
varsl[]int
funcadd(){
forindex:=0;indexindex++{
sl=append(sl,index)
wg.Done()
funcmain(){
wg.Add(2)
goadd()
goadd()
wg.Wait()
fmt.Println(sl)
fmt.Printf("finallen(sl)=%dcap(sl)=%d\n",len(sl),cap(sl))
[012345678910111213141516171819202122232425262728293031012345678910111213141516171819202122232425262728293031323334
353637383940414243444546474849]
finallen(sl)=82cap(sl)=128
}
加鎖
packagemain
import(
"fmt"
"sync"
varwgsync.WaitGroup
varsl[]int
varlocksync.Mutex
funcadd(){
forindex:=0;indexindex++{
lock.Lock()
sl=append(sl,index)
lock.Unlock()
wg.Done()
funcmain(){
wg.Add(2)
goadd()
goa
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 屋內(nèi)環(huán)境衛(wèi)生制度
- 臥室衛(wèi)生管理制度
- 員工培訓(xùn)體檢衛(wèi)生制度
- 小學(xué)衛(wèi)生教育培訓(xùn)制度
- 衛(wèi)生罰款規(guī)章制度
- 衛(wèi)生急救培訓(xùn)演練制度
- 學(xué)校衛(wèi)生工具領(lǐng)用制度
- 衛(wèi)生許可九個(gè)制度
- 養(yǎng)殖清潔衛(wèi)生制度
- 溫泉洗浴衛(wèi)生制度
- 【生物】種子的萌發(fā)-2024-2025學(xué)年七年級(jí)生物下冊(cè)同步教學(xué)課件(人教版2024)
- 光伏發(fā)電安裝質(zhì)量驗(yàn)收評(píng)定表
- AQ 1046-2007 地勘時(shí)期煤層瓦斯含量測(cè)定方法(正式版)
- 房屋過(guò)戶(hù)給子女的協(xié)議書(shū)的范文
- 超聲振動(dòng)珩磨裝置的總體設(shè)計(jì)
- 新媒體藝術(shù)的發(fā)展歷程及藝術(shù)特征
- 醫(yī)保違規(guī)行為分類(lèi)培訓(xùn)課件
- 講課學(xué)生數(shù)學(xué)學(xué)習(xí)成就
- 醫(yī)療器械法規(guī)對(duì)互聯(lián)網(wǎng)銷(xiāo)售的限制
- 系桿拱橋系桿預(yù)應(yīng)力施工控制要點(diǎn)
- 三亞市海棠灣椰子洲島土地價(jià)格咨詢(xún)報(bào)告樣本及三洲工程造價(jià)咨詢(xún)有限公司管理制度
評(píng)論
0/150
提交評(píng)論