【Java多線程】多線程狀態下如何安全使用ArrayList以及哈希表

在這里插入圖片描述

🔍 開發者資源導航 🔍
🏷? 博客主頁: 個人主頁
📚 專欄訂閱: JavaEE全棧專欄

多線程安全使用ArrayList

手動加鎖

日常中最常用的方法,使用synchronized進行加鎖,把代碼打包成一份,使其成為一個“原子”操作。

手動加鎖:可以只鎖必要的部分,減少競爭。適用于高并發場景。

使用Collections套殼

Collections.synchronizedList() 返回一個 線程安全的 List 包裝器,所有對 List 的操作(如 add(), remove(), get())都會自動加鎖,確保多線程安全。

 List<Integer> arr = Collections.synchronizedList(new ArrayList<Integer>());

缺點:

  1. synchronizedList 只保證單個操作是原子的,但 遍歷(iteration)仍然需要手動加鎖。
  2. 鎖的粒度較大,導致:高并發寫操作時,線程會頻繁競爭同一把鎖,造成阻塞(contention)。讀操作也會被阻塞(即使讀操作本身不修改數據)。

適用于適用于低并發(少量寫操作)。

CopyOnWriteArrayList

CopyOnWriteArrayList在操作時不去加鎖,它在進行讀寫操作時使用了一種常見的思想方法:寫時拷貝。

他在修改時,先創建一個相同的數組,對這個新的數組進行修改操作,然后改變原數組的引用。

雖然復制過程不是原子的,但是由于提供了舊版本的數組,不影響其他線程讀取。
在這里插入圖片描述
優點:
沒有加鎖~不會產生阻塞。

缺點:

  1. 如果數組很大,效率會非常大。
  2. 多個線程同時修改,也容易出現問題,可以會丟失修改數據。
  3. 只適用于特定場景,例如:服務器進行重新加載配置的時候。

多線程安全使用哈希表

Hashtable

Hashtable相比于Hashmap對各種public方法都加了synchronized,可以保證線程安全。

缺點:對整個哈希表進行了加鎖,在訪問時很容易造成競爭,造成效率降低。

ConcurrentHashMap

基于哈希表進行的多線程優化,他按照桶級別進行加鎖,而不是加一個全局鎖,有效降低鎖沖突的概率。

優化點一

在Hashtable中任意的兩個線程訪問不同的兩個元素都會造成競爭,但是實際上,處于兩個不同鏈表上的兩個元素是不會涉及線程安全問題的。

因此ConcurrentHashMap對每一個節點都分配一個鎖,可以減少修改不同變量時的鎖競爭。

那么這樣做會增加它占的空間嗎?在Java中每一個對象都可以作為鎖對象,因此我們完全可以讓每一個鏈表的頭結點當做鎖對象,因此并不會增加空間。

優化點二
上述優化點雖然可以減少鎖競爭,但是卻無法保證size()方法的線程安全,因為它的鎖不是全局鎖了,而是分別加鎖。因此ConcurrentHashMap的size改用了原子類進行存儲。

優化點三
ConcurrentHashMap針對擴容操作也進行了優化,在把舊哈希的元素搬運到新的哈希過程中,如果元素很多,耗時就會很長。

ConcurrentHashMap針對擴容的操作將其化整為零,既然一口氣搬運比較好使,那就一次只搬一部分,這樣的操作可以將擴容的耗時平均分擔開,而不會造成某次的操作時間過長。


感謝各位的觀看Thanks?(・ω・)ノ,如果覺得滿意的話留個關注再走吧。

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

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

相關文章

InnoDB引擎底層解析(二)之InnoDB的Buffer Pool(三)

Buffer Pool 實例 我們上邊說過&#xff0c;Buffer Pool 本質是 InnoDB 向操作系統申請的一塊連續的內存空間&#xff0c;在多線程環境下&#xff0c;訪問 Buffer Pool 中的各種鏈表都需要加鎖處理&#xff0c;在Buffer Pool特別大而且多線程并發訪問特別高的情況下&#xff0…

Netty學習專欄(三):Netty重要組件詳解(Future、ByteBuf、Bootstrap)

文章目錄 前言一、Future & Promise&#xff1a;異步編程的救星1.1 傳統NIO的問題1.2 Netty的解決方案1.3 代碼示例&#xff1a;鏈式異步操作 二、ByteBuf&#xff1a;重新定義數據緩沖區2.1 傳統NIO ByteBuffer的缺陷2.2 Netty ByteBuf的解決方案2.3 代碼示例&#xff1a;…

Vue3逐步拋棄虛擬Dom,React如何抉擇

虛擬DOM&#xff1a;前端界的替死鬼 這玩意兒就是個前端開發的充氣娃娃&#xff01; 你以為它很牛逼&#xff1f;無非是給真DOM當替死鬼&#xff01; 每次數據變&#xff0c;虛擬DOM先擱內存里自嗨一頓&#xff0c;diff算法跟便秘似的算半天&#xff0c;最后才敢碰真DOM。 說白…

分布式鎖總結

文章目錄 分布式鎖什么是分布式鎖&#xff1f;分布式鎖的實現方式基于數據庫(mysql)實現基于緩存(redis)多實例并發訪問問題演示項目代碼(使用redis)配置nginx.confjmeter壓測復現問題并發是1&#xff0c;即不產生并發問題并發30測試,產生并發問題(雖然單實例是synchronized&am…

解決自簽名證書HTTPS告警:強制使用SHA-256算法生成證書

解決自簽名證書HTTPS告警&#xff1a;強制使用SHA-256算法生成證書 一、問題場景 在使用OpenSSL生成和配置自簽名證書時&#xff0c;常遇到以下現象&#xff1a; 瀏覽器已正確導入根證書&#xff08;.pem文件&#xff09;&#xff0c;但訪問HTTPS站點時仍提示不安全連接或證…

線上 Linux 環境 MySQL 磁盤 IO 高負載深度排查與性能優化實戰

目錄 一、線上告警 二、問題診斷 1. 系統層面排查 2. 數據庫層面分析 三、參數調優 1. sync_binlog 參數優化 2. innodb_flush_log_at_trx_commit 參數調整 四、其他優化建議 1. 日志文件位置調整 2. 生產環境核心參數配置模板 3. 突發 IO 高負載應急響應方案 五、…

window 顯示驅動開發-初始化和 DMA 緩沖區創建

若要指示 GPU 支持 GDI 硬件加速&#xff0c;顯示微型端口驅動程序的 DriverEntry 函數實現必須使用指向驅動程序實現的 DxgkDdiRenderKm 函數的指針填充 DRIVER_INITIALIZATION_DATA 結構的 DxgkDdiRenderKm 成員。 DirectX 圖形內核子系統調用 DxgkDdiRenderKm 函數&#xf…

Go語言實戰:使用 excelize 實現多層復雜Excel表頭導出教程

Go 實現支持多層復雜表頭的 Excel 導出工具 目錄 項目介紹依賴說明核心結構設計如何支持多層表頭完整使用示例總結與擴展 項目介紹 在實際業務系統中&#xff0c;Excel 文件導出是一項常見功能&#xff0c;尤其是報表類需求中常見的復雜多級表頭&#xff0c;常規表格組件往…

機器視覺6-halcon高級教程

機器視覺6-halcon高級教程 雙目立體視覺原理視差外極線幾何雙目標定 雙目立體視覺之Halcon標定一&#xff0e;標定結果二.Halcon標定過程1.獲取左右相機圖像中標定板的區域;2.提取左右相機圖像中標定板的MARK點坐標和攝像機外部參數;3.執行雙目標定;4.獲取非標準外極線幾何到標…

板凳-------Mysql cookbook學習 (六)

2025年Pytorch-gpu版本安裝&#xff08;各種情況適用自己的安裝需求&#xff0c;親測絕對有效&#xff0c;示例安裝torch2.6.0&#xff0c;過程詳細面向小白&#xff09;_torch gpu版本-CSDN博客 https://blog.csdn.net/OpenSeek/article/details/145795127 2.2 查錯 import s…

Spring boot和SSM項目對比

目錄對比 springboot目錄 project├─src│ ├─main│ │ ├─java│ │ │ ├─com.example.demo│ │ │ │ ├─config // 存放SpringBoot的配置類│ │ │ │ ├─controller // 存放控制器類│ │ │ │ ├─entity // 存…

《關于潯川社團退出DevPress社區及內容撤回的聲明》

《關于潯川社團退出DevPress社區及內容撤回的聲明》 尊敬的DevPress社區及讀者&#xff1a; 經潯川社團內部決議&#xff0c;我社決定自**2025年5月26日**起正式退出DevPress社區&#xff0c;并撤回所有由我社成員在該平臺發布的原創文章。相關事項聲明如下&#xff1a; …

Python性能優化利器:__slots__的深度解析與避坑指南

核心場景&#xff1a;當需要創建數百萬個屬性固定的對象時&#xff0c;默認的__dict__字典存儲會造成巨大內存浪費。此時__slots__能通過元組結構取代字典&#xff0c;顯著提升內存效率&#xff08;實測節省58%內存&#xff09;&#xff01; 底層原理&#xff1a;為何能節省內…

Go 語言中的 Struct Tag 的用法詳解

在 Go 語言中&#xff0c;結構體字段標簽&#xff08;Struct Tag&#xff09; 是一種用于給字段添加元信息&#xff08;metadata&#xff09;的機制&#xff0c;常用于序列化&#xff08;如 JSON、XML&#xff09;、ORM 映射、驗證等場景。你在開發 Web 應用或處理數據交互時&a…

微軟正式發布 SQL Server 2025 公開預覽版,深度集成AI功能

微軟在今年的 Build 2025 大會上正式發布了 SQL Server 2025 公開預覽版&#xff0c;標志著這一經典數據庫產品在 AI 集成、安全性、性能及開發者工具方面的全面升級。 AI 深度集成與創新 原生向量搜索&#xff1a;SQL Server 2025 首次將 AI 功能直接嵌入數據庫引擎&#xff…

React從基礎入門到高級實戰:React 基礎入門 - React 的工作原理:虛擬 DOM 與 Diff 算法

React 的工作原理&#xff1a;虛擬 DOM 與 Diff 算法 引言 React 是現代前端開發的明星框架&#xff0c;它的出現徹底改變了我們構建用戶界面的方式。無論是動態的 Web 應用還是復雜的單頁應用&#xff08;SPA&#xff09;&#xff0c;React 都能以高效的渲染機制和簡潔的組件…

解釋一下NGINX的反向代理和正向代理的區別?

大家好&#xff0c;我是鋒哥。今天分享關于【解釋一下NGINX的反向代理和正向代理的區別?】面試題。希望對大家有幫助&#xff1b; 解釋一下NGINX的反向代理和正向代理的區別? NGINX的反向代理和正向代理的區別主要體現在它們的功能和使用場景上。下面我會詳細解釋它們的定義…

Python學習——執行python時,鍵盤按下ctrl+c,退出程序

在 Python 中&#xff0c;當用戶按下 CtrlC 時&#xff0c;程序默認會觸發 KeyboardInterrupt 異常并終止。 1. 捕獲 KeyboardInterrupt 異常&#xff08;推薦&#xff09; 使用 try-except 塊直接捕獲 KeyboardInterrupt 異常&#xff0c;適用于簡單場景。 示例代碼&#xff…

C++ 反向迭代器(Reverse Iterator)實現詳解

目錄 1. 反向迭代器概述 2. 代碼實現分析 3. 關鍵點解析 3.1 模板參數設計 3.2 核心操作實現 4. 使用示例 1. 反向迭代器概述 反向迭代器是STL中一種重要的適配器&#xff0c;它允許我們以相反的順序遍歷容器。本文將詳細講解如何實現一個自定義的反向迭代器模板類。 2.…

動態DNS管理:【etcd+CoreDNS】 vs【BIND9】便捷性對比

對比 BIND9 集群和 etcdCoreDNS 集群在便捷性方面&#xff0c;通常情況下&#xff0c;對于需要動態、頻繁變更 DNS 記錄以及追求云原生和自動化集成的場景&#xff0c;etcdCoreDNS 方案更加便捷。 然而&#xff0c;“便捷性”也取決于具體的應用場景、團隊的技術棧和運維習慣。…