Go語言實戰案例:使用sync.Map構建線程安全map

在并發編程中,共享資源的訪問是一個繞不開的問題。Go 中的?map?在并發讀寫時是不安全的,直接使用可能導致程序 panic。因此,在多協程同時訪問 Map 的場景下,必須采取有效的同步措施。

本篇將通過一個實戰案例,介紹 Go 的并發神器 ——?sync.Map,并展示其使用方式和應用場景。


一、為什么普通?map?不安全?

m?:=?make(map[string]int)go?func()?{m["a"]?=?1
}()go?func()?{fmt.Println(m["a"])
}()

上述代碼在運行時,極有可能 panic

fatal?error:?concurrent?map?read?and?map?write

這是因為 Go 的原生?map?類型并不支持并發讀寫。


二、解決方式有哪些?

  1. 1. 使用?sync.Mutex?+ map 手動加鎖;
  2. 2. 使用?sync.RWMutex?讀寫分離鎖;
  3. 3. 使用 Go 官方提供的?sync.Map?—— 最簡便的線程安全 map 實現!

三、什么是?sync.Map

sync.Map?是 Go 標準庫提供的并發安全 map,特點包括:

  • ? 內置鎖機制,適合高并發讀寫;
  • ? 無需手動加鎖;
  • ? 內部采用讀優化結構(讀多寫少場景性能更佳);
  • ? 提供一組特定 API(不能用下標訪問,如?m["a"])。

四、實戰案例:使用?sync.Map?構建并發計數器

我們實現一個并發訪問的計數器,多個 goroutine 同時對多個 key 進行訪問和計數。

示例代碼:
package?mainimport?("fmt""sync""time"
)func?main()?{var?counter?sync.Mapvar?wg?sync.WaitGroupkeys?:=?[]string{"A",?"B",?"C"}//?每個?key?啟動?10?個協程并發計數for?_,?key?:=?range?keys?{for?i?:=?0;?i?<?10;?i++?{wg.Add(1)go?func(k?string)?{defer?wg.Done()for?j?:=?0;?j?<?100;?j++?{//?原子更新?key?的計數val,?_?:=?counter.LoadOrStore(k,?0)counter.Store(k,?val.(int)+1)}}(key)}}wg.Wait()//?打印結果counter.Range(func(k,?v?any)?bool?{fmt.Printf("Key:?%s,?Count:?%d\n",?k,?v)return?true})
}

五、輸出示例:

Key:?A,?Count:?1000
Key:?B,?Count:?1000
Key:?C,?Count:?1000

六、常用方法介紹:

方法功能描述
Load(key)獲取鍵對應的值和是否存在
Store(key, value)設置鍵值
LoadOrStore(key, value)獲取已存在值,否則存入新值
Delete(key)刪除指定鍵值對
Range(func(k, v any) bool)遍歷所有鍵值對,返回 false 可中斷遍歷

七、注意事項

  1. 1.?無法使用?m["key"]?形式,只能通過?Load?/?Store
  2. 2.?LoadOrStore?非原子加法操作:如本例中?val + 1?不是并發安全操作;
    • ? 更好的方式是配合原子操作?sync/atomic?或引入鎖;
  3. 3.?sync.Map?更適合“讀多寫少”的場景;
  4. 4. 若是寫多場景,建議仍用?RWMutex + map?自行控制。

八、應用場景舉例

  • ? 統計類服務:如 PV/UV 實時統計;
  • ? 緩存系統:緩存熱點數據;
  • ? 注冊中心:維護在線服務列表;
  • ? 連接池管理:存儲連接狀態;

九、總結

sync.Map?提供了一種簡潔、高效的方式來處理并發情況下的共享數據。它避免了手動加鎖的繁瑣,讓我們更專注于業務邏輯。

? 并發安全
? 使用簡單
? 性能優越(適合讀多寫少)


下一個實戰案例:我們將結合?context + sync.Map?實現帶過期控制的并發緩存服務,敬請關注!


🔧 附加福利:你可以這樣封裝自己的線程安全結構

type?SafeMap?struct?{data?sync.Map
}func?(sm?*SafeMap)?Incr(key?string)?{for?{val,?_?:=?sm.data.LoadOrStore(key,?0)newVal?:=?val.(int)?+?1sm.data.Store(key,?newVal)break}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/92432.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/92432.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/92432.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

關于vue2中對接海康攝像頭以及直播流rtsp或rtmp,后臺ffmpeg轉碼后通過ws實現

最近項目中需要對接攝像頭監控&#xff0c;海康攝像頭為rtsp流格式有一個軟件VLC media player&#xff0c;可以在線進行rtsp或者rtmp流播放&#xff0c;可用來測試流地址是否可用功能實現思路為后臺通過fmpeg把rtsp流進行轉碼&#xff0c;然后通過ws方式進行一幀一幀推送。&am…

Docker容器強制刪除及文件系統修復完整指南

Docker容器強制刪除及文件系統修復完整指南 故障現象與原因分析 ?故障表現?&#xff1a; ERROR: for c9ca40be974d_OpIsosMD_OB unable to remove filesystem unlinkat /data/docker/storage/containers/c9ca40be974d...: structure needs cleaning?根本原因?&#xff1a;…

Matplotlib 知識點總結

1. 基礎繪圖&#xff08;plot函數&#xff09;基本語法&#xff1a;plot([x], y, [fmt], [x2], y2, [fmt2], ..., **kwargs)功能特點&#xff1a;可繪制點、線和組合圖形自動生成x軸&#xff08;0-N-1&#xff09;當x未指定時示例&#xff1a;繪制兩點連線、多點不規則線等代碼…

高可用微服務架構實戰:Nacos集群+Nginx負載均衡,Spring Cloud無縫對接

"當你的注冊中心掛了&#xff0c;整個微服務就變成了無頭蒼蠅。" 這是我在生產環境踩坑后最痛的領悟。今天&#xff0c;我將分享如何用Nacos集群Nginx搭建堅如磐石的注冊中心&#xff0c;讓你的微服務永不迷路&#xff01; 在 Windows 環境下配置 Nacos 集群&#x…

Spark大數據處理實戰指南

Spark 簡介 Apache Spark 是一個開源的分布式計算框架,專為大規模數據處理而設計。它通過內存計算和優化的執行引擎顯著提升了數據處理速度,適用于批處理、實時流處理、機器學習和圖計算等場景。 核心特性 高性能:利用內存計算(In-Memory Processing)減少磁盤 I/O,比傳…

瀏覽器緩存機制全解析:強緩存與協商緩存

瀏覽器緩存是瀏覽器為提升頁面加載速度、減少服務器壓力和節省網絡帶寬&#xff0c;在本地存儲資源&#xff08;如 HTML、CSS、JS、圖片等&#xff09;的機制。其核心分為強緩存和協商緩存&#xff0c;并涉及多種 HTTP 頭字段和存儲位置。以下是詳細解析&#xff1a;?? 一、緩…

知識隨記-----Qt 實用技巧:自定義倒計時按鈕防止用戶頻繁點擊

Qt 技巧&#xff1a;實現自定義倒計時按鈕防止用戶頻繁點擊注冊 項目場景 在一個基于 Qt 開發的聊天應用中&#xff0c;用戶注冊時需要獲取驗證碼。為防止用戶頻繁點擊獲取驗證碼按鈕&#xff0c;需要實現一個倒計時功能&#xff0c;用戶點擊后按鈕進入倒計時狀態&#xff0c;倒…

Linux與Windows應急響應

本人首先進行了linux的應急響應&#xff0c;windows之后再進行 Linux與Windows應急響應初體驗1 linux應急響應1.1 賬戶&#xff1a;1.1.1 使用cat /etc/passwd命令查看passwd文件2.1.2 使用cat /etc/shadow命令查找shadow文件&#xff0c;該文件為密碼文件的存儲項1.2 入侵排查…

計算機網絡1-4:計算機網絡的定義和分類

目錄 計算機網絡的定義 計算機網絡的分類 計算機網絡的定義 計算機網絡的分類 按交換技術分類&#xff1a;電路交換網絡、報文交換網絡、分組交換網絡 按使用者分類&#xff1a;公用網、專用網 按傳輸介質分類&#xff1a;有線網絡、無線網絡 按覆蓋范圍分類&#xff1a;…

在QT中動態添加/刪除控件,伸縮因子該怎么處理

開發中遇到的問題[TOC](開發中遇到的問題)處理方式在我們的界面開發過程中&#xff0c;通常需要開發一些可以動態添加or刪除控件的容器&#xff0c;類似Tab頁一樣&#xff0c;為了美觀的話&#xff0c;我們通常使用伸縮因子將容器中的控件往一個方向擠&#xff0c;類似下面的控…

【設計模式精解】什么是代理模式?徹底理解靜態代理和動態代理

目錄 靜態代理 動態代理 JDK動態代理 CGLIB代理 JDK動態代理和CGLIB代理的區別 總結 代理模式簡單來說就是 我們使用代理對象來代替對真實對象(real object)的訪問&#xff0c;這樣就可以在不修改原目標對象的前提下&#xff0c;擴展目標對象的功能。 代理模式有靜態代理…

MCU AI/ML - 彌合智能和嵌入式系統之間的差距

作者&#xff1a;芯科科技產品營銷高級經理Gopinath Krishniah 人工智能&#xff08;AI&#xff09;和機器學習&#xff08;ML&#xff09;是使系統能夠從數據中學習、進行推理并隨著時間的推移提高性能的關鍵技術。這些技術通常用于大型數據中心和功能強大的GPU&#xff0c;但…

Redis中的sdshdr的len和alloc那塊的知識點詳解

文章目錄核心比喻&#xff1a;一個可以伸縮的水瓶場景一&#xff1a;創建一個新字符串場景二&#xff1a;追加字符串&#xff08;觸發“空間預分配”&#xff09;場景三&#xff1a;再次追加字符串&#xff08;利用空閑空間&#xff09;場景四&#xff1a;縮短字符串&#xff0…

在Linux下訪問MS SQL Server數據庫

Linux作為一個免費的Unix類操作系統&#xff0c;以其開放性源代碼、多任務、X window等特點為眾多的用戶所采用&#xff0c;并有很多企業采用Linux來作為其內部網的全功能服務器(WWW&#xff0c;FTP&#xff0c;Email、DNS)。企業的內部網不僅要提供文本信息的訪問&#xff0c;…

計算機視覺-OpenCV

一下載第三方庫opencv-python3.4.18.65opencv-contrib-python3.4.18.65import cv2 # 讀取的格式是BGR numpy import numpy as np# 讀取圖片 a cv2.imread(generated_image.jpg) # 讀取圖片 print(a) # NumPy數組&#xff0c;其中存儲了讀取的圖像文件的像素值。cv2.imshow…

解決GitHub無法打開

找到下圖文件&#xff0c;用記事本打開 在最下方粘貼如下代碼140.82.113.4 github.com 20.205.243.166 github.com 140.82.112.4 github.com 151.101.1.6 github.global.ssl.fastly.net 185.199.108.153 assets-cdn.github.com 185.199.109.153 assets-cdn.github.com 185.199.…

AWS VPC Transit Gateway 可觀測最佳實踐

AWS VPC Transit Gateway 介紹 Amazon VPC Transit Gateway 是一個網絡傳輸中心&#xff0c;用于互連虛擬私有云 (VPCs) 和本地網絡。隨著您的云基礎設施在全球擴展&#xff0c;區域間對等互連使用 AWS 全球基礎設施將中轉網關連接在一起。 AWS 數據中心之間的所有網絡流量都在…

WeakRef的作用和使用

文章目錄WeakRef的作用和使用使用 WeakRef 避免強引用&#xff1a;原理與實踐一、WeakRef 的核心特性二、WeakRef 與強引用的對比三、WeakRef 的使用場景與示例1. 非關鍵數據緩存&#xff08;避免緩存導致內存泄漏&#xff09;2. 跟蹤對象生命周期&#xff08;不干擾回收&#…

【華為機試】332. 重新安排行程

文章目錄332. 重新安排行程題目描述示例 1&#xff1a;示例 2&#xff1a;提示&#xff1a;解題思路核心思路算法流程圖歐拉路徑原理DFS回溯機制字典序優化策略復雜度分析算法實現要點完整題解代碼332. 重新安排行程 題目描述 給你一份航線列表 tickets &#xff0c;其中 tic…

通信算法之300:CRC表生成方式-CRC8、CRC16、CRC32-輸入字節

"CRC表的MATLAB生成代碼"生成的查找表可以用于快速計算 CRC 值&#xff0c;通過查表法可以顯著提高 CRC 計算效率&#xff0c;尤其適用于需要處理大量數據的場景。下面是一個生成 CRC 查找表&#xff08;CRC Table&#xff09;的 MATLAB 代碼&#xff0c;該代碼可以根…