Go語言中map使用和并發(fā)安全詳解_第1頁
Go語言中map使用和并發(fā)安全詳解_第2頁
Go語言中map使用和并發(fā)安全詳解_第3頁
Go語言中map使用和并發(fā)安全詳解_第4頁
Go語言中map使用和并發(fā)安全詳解_第5頁
已閱讀5頁,還剩3頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

第Go語言中map使用和并發(fā)安全詳解目錄1map使用1.1map定義1.2map的使用和概念1.3map的容量1.4map的使用1.4.1map的遍歷1.4.2map的刪除和斷言1.5map的坑2并發(fā)安全2.1不安全原因2.2解決方案總結

1map使用

1.1map定義

map是一種無序的集合,對應的key(索引)會對應一個value(值),所以這個結構也稱為關聯(lián)數(shù)組或字典。

map在其他語言中hash、hashtable等

varmapnamemap[keytype]valuetype

mapname為map的變量名。keytype為鍵類型。valuetype是鍵對應的值類型。

1.2map的使用和概念

map是引用類型,未初始化的map是nil

packagemain

import"fmt"

funcmain(){

varmaplistmap[string]int

maplist["one"]=1

fmt.Println(maplist)

//報錯:panic:assignmenttoentryinnilmap

//map需要先初始化內存后使用

正確做法:

packagemain

import"fmt"

funcmain(){

varmaplistmap[string]int

maplist=map[string]int{"one":1,"two":2}

maplist["three"]=3

fmt.Println(maplist)

//map[one:1three:3two:2]

當然也可以這樣子:

packagemain

import"fmt"

funcmain(){

maplist:=make(map[string]int)//初始化內存了,想賦值就賦值

maplist["three"]=3

fmt.Println(maplist)

map必須先初始化內存,后使用,也就是需要make一下,或者直接賦值一個空map

maplist:=map[string]int{}

fmt.Println(maplist)

1.3map的容量

和數(shù)組不同的是,map可以根據(jù)新增的key-value動態(tài)的伸縮,因此不存在固定長度或者最大限制,但是也可以選擇初始化容量的值

maplist:=make(map[string]float,100)

出于性能考慮,對于大的map或者快速擴張的map,最好先標明

用切片作為map的值

maplist1:=make(map[int][]int)

maplist2:=make(map[int]*[]int)

golang里的類型使用靈活,也可以任意組合,map里的值可以是struct,也可以是int、string、甚至是切片、數(shù)組。

1.4map的使用

1.4.1map的遍歷

scene:=make(map[string]int)

scene["route"]=66

scene["brazil"]=4

scene["china"]=960

fork,v:=rangescene{

fmt.Println(k,v)

1.4.2map的刪除和斷言

packagemain

import"fmt"

funcmain(){

maplist:=make(map[string]int)

//準備map數(shù)據(jù)

maplist["LYY"]=66

maplist["520"]=4

maplist["666"]=960

delete(maplist,"666")

fork,v:=rangemaplist{

fmt.Println(k,v)

1.5map的坑

packagemain

import"fmt"

funcmain(){

m:=map[int]struct{}{

1:{},

2:{},

3:{},

4:{},

5:{},

fork:=rangem{

fmt.Println(k)

//沒有設置v值的時候,map的遍歷是隨機的,起始遍歷是個隨機值

執(zhí)行第一次:

執(zhí)行第二次:

注意:map在增加值、刪除時需要加互斥鎖

2并發(fā)安全

Go語言中的map在并發(fā)情況下,只讀是線程安全的,同時讀寫是線程不安全的。

2.1不安全原因

官網(wǎng)解釋:同一個變量在多個goroutine中訪問需要保證其安全性。

packagemain

import(

"fmt"

"time"

varTestMapmap[string]string

funcinit(){

TestMap=make(map[string]string,1)

funcmain(){

fori:=0;i1000;i++{

goWrite("aaa")

goRead("aaa")

goWrite("bbb")

goRead("bbb")

time.Sleep(5*time.Second)

funcRead(keystring){

fmt.Println(TestMap[key])

funcWrite(keystring){

TestMap[key]=key

//報錯fatalerror:concurrentmapwrites

原因:因為map變量為指針類型變量,并發(fā)寫時,多個協(xié)程同時操作一個內存,類似于多線程操作同一個資源會發(fā)生競爭關系,共享資源會遭到破壞,因此golang出于安全的考慮,拋出致命錯誤:fatalerror:concurrentmapwrites。

2.2解決方案

(1)在寫操作的時候增加鎖,刪除時候除了加鎖外,還需要增加斷言避免出現(xiàn)錯誤

packagemain

import(

"fmt"

"sync"

funcmain(){

varlocksync.Mutex

varmaplistmap[string]int

maplist=map[string]int{"one":1,"two":2}

lock.Lock()

maplist["three"]=3

lock.Unlock()

fmt.Println(maplist)

執(zhí)行結果:

(2)sync.Map包

packagemain

import(

"fmt"

"sync"

funcmain(){

m:=sync.Map{}//或者varmmsync.Map

m.Store("a",1)

m.Store("b",2)

m.Store("c",3)//插入數(shù)據(jù)

fmt

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論