日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
創(chuàng)新互聯(lián)GO教程:Go語言sync.Map(在并發(fā)環(huán)境中使用的map)

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

下面來看下并發(fā)情況下讀寫 map 時(shí)會(huì)出現(xiàn)的問題,代碼如下:

// 創(chuàng)建一個(gè)int到int的映射
m := make(map[int]int)

// 開啟一段并發(fā)代碼
go func() {

    // 不停地對map進(jìn)行寫入
    for {
        m[1] = 1
    }

}()

// 開啟一段并發(fā)代碼
go func() {

    // 不停地對map進(jìn)行讀取
    for {
        _ = m[1]
    }

}()

// 無限循環(huán), 讓并發(fā)程序在后臺執(zhí)行
for {

}

運(yùn)行代碼會(huì)報(bào)錯(cuò),輸出如下:

fatal error: concurrent map read and map write

錯(cuò)誤信息顯示,并發(fā)的 map 讀和 map 寫,也就是說使用了兩個(gè)并發(fā)函數(shù)不斷地對 map 進(jìn)行讀和寫而發(fā)生了競態(tài)問題,map 內(nèi)部會(huì)對這種并發(fā)操作進(jìn)行檢查并提前發(fā)現(xiàn)。

需要并發(fā)讀寫時(shí),一般的做法是加鎖,但這樣性能并不高,Go語言在 1.9 版本中提供了一種效率較高的并發(fā)安全的 sync.Map,sync.Map 和 map 不同,不是以語言原生形態(tài)提供,而是在 sync 包下的特殊結(jié)構(gòu)。

sync.Map 有以下特性:

  • 無須初始化,直接聲明即可。
  • sync.Map 不能使用 map 的方式進(jìn)行取值和設(shè)置等操作,而是使用 sync.Map 的方法進(jìn)行調(diào)用,Store 表示存儲(chǔ),Load 表示獲取,Delete 表示刪除。
  • 使用 Range 配合一個(gè)回調(diào)函數(shù)進(jìn)行遍歷操作,通過回調(diào)函數(shù)返回內(nèi)部遍歷出來的值,Range 參數(shù)中回調(diào)函數(shù)的返回值在需要繼續(xù)迭代遍歷時(shí),返回 true,終止迭代遍歷時(shí),返回 false。

并發(fā)安全的 sync.Map 演示代碼如下:

package main

import (
      "fmt"
      "sync"
)

func main() {

    var scene sync.Map

    // 將鍵值對保存到sync.Map
    scene.Store("greece", 97)
    scene.Store("london", 100)
    scene.Store("egypt", 200)

    // 從sync.Map中根據(jù)鍵取值
    fmt.Println(scene.Load("london"))

    // 根據(jù)鍵刪除對應(yīng)的鍵值對
    scene.Delete("london")

    // 遍歷所有sync.Map中的鍵值對
    scene.Range(func(k, v interface{}) bool {

        fmt.Println("iterate:", k, v)
        return true
    })

}

代碼輸出如下:

100 true
iterate: egypt 200
iterate: greece 97

代碼說明如下:

  • 第 10 行,聲明 scene,類型為 sync.Map,注意,sync.Map 不能使用 make 創(chuàng)建。
  • 第 13~15 行,將一系列鍵值對保存到 sync.Map 中,sync.Map 將鍵和值以 interface{} 類型進(jìn)行保存。
  • 第 18 行,提供一個(gè) sync.Map 的鍵給 scene.Load() 方法后將查詢到鍵對應(yīng)的值返回。
  • 第 21 行,sync.Map 的 Delete 可以使用指定的鍵將對應(yīng)的鍵值對刪除。
  • 第 24 行,Range() 方法可以遍歷 sync.Map,遍歷需要提供一個(gè)匿名函數(shù),參數(shù)為 k、v,類型為 interface{},每次 Range() 在遍歷一個(gè)元素時(shí),都會(huì)調(diào)用這個(gè)匿名函數(shù)把結(jié)果返回。

sync.Map 沒有提供獲取 map 數(shù)量的方法,替代方法是在獲取 sync.Map 時(shí)遍歷自行計(jì)算數(shù)量,sync.Map 為了保證并發(fā)安全有一些性能損失,因此在非并發(fā)情況下,使用 map 相比使用 sync.Map 會(huì)有更好的性能。


當(dāng)前標(biāo)題:創(chuàng)新互聯(lián)GO教程:Go語言sync.Map(在并發(fā)環(huán)境中使用的map)
文章轉(zhuǎn)載:http://m.5511xx.com/article/dppsisc.html