AVt天堂网 手机版,亚洲va久久久噜噜噜久久4399,天天综合亚洲色在线精品,亚洲一级Av无码毛片久久精品

當(dāng)前位置:首頁(yè) > 科技  > 軟件

如何線程安全的使用 HashMap

來(lái)源: 責(zé)編: 時(shí)間:2024-06-05 17:44:50 154觀看
導(dǎo)讀這篇文章,我們聊聊線程安全使用 HashMap 的四種技巧。圖片1.方法內(nèi)部:每個(gè)線程創(chuàng)建單獨(dú)的 HashMap如下圖,tomcat 接收到到請(qǐng)求后,依次調(diào)用控制器 Controller、服務(wù)層 Service 、數(shù)據(jù)庫(kù)訪問(wèn)層的相關(guān)方法。每次訪問(wèn)服務(wù)層方

這篇文章,我們聊聊線程安全使用 HashMap 的四種技巧。HM728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片HM728資訊網(wǎng)——每日最新資訊28at.com

1.方法內(nèi)部:每個(gè)線程創(chuàng)建單獨(dú)的 HashMap

如下圖,tomcat 接收到到請(qǐng)求后,依次調(diào)用控制器 Controller、服務(wù)層 Service 、數(shù)據(jù)庫(kù)訪問(wèn)層的相關(guān)方法。HM728資訊網(wǎng)——每日最新資訊28at.com

每次訪問(wèn)服務(wù)層方法 serviceMethod 時(shí),都會(huì)在方法體內(nèi)部創(chuàng)建一個(gè)單獨(dú)的 HashMap ,  將相關(guān)請(qǐng)求參數(shù)拷貝到 HashMap 里,然后調(diào)用 DAO 方法進(jìn)行數(shù)據(jù)庫(kù)操作。HM728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片HM728資訊網(wǎng)——每日最新資訊28at.com

每個(gè) HTTP 處理線程在服務(wù)層方法體內(nèi)部都有自己的 HashMap 實(shí)例,在多線程環(huán)境下,不需要對(duì) HashMap 進(jìn)行任何同步操作。HM728資訊網(wǎng)——每日最新資訊28at.com

這也是我們使用最普遍也最安全的的方式,是 CRUD 最基本的操作。HM728資訊網(wǎng)——每日最新資訊28at.com

2.配置數(shù)據(jù):初始化單線程寫,后續(xù)只提供讀

系統(tǒng)啟動(dòng)之后,我們可以將配置數(shù)據(jù)加載到本地緩存 HashMap 里 ,這些配置信息初始化之后,就不需要寫入了,后續(xù)只提供讀操作。HM728資訊網(wǎng)——每日最新資訊28at.com

圖片圖片HM728資訊網(wǎng)——每日最新資訊28at.com

上圖中顯示一個(gè)非常簡(jiǎn)單的配置類 SimpleConfig ,內(nèi)部有一個(gè) HashMap 對(duì)象 configMap 。構(gòu)造函數(shù)調(diào)用初始化方法,初始化方法內(nèi)部的邏輯是:將配置數(shù)據(jù)存儲(chǔ)到 HashMap 中。HM728資訊網(wǎng)——每日最新資訊28at.com

SimpleConfig 類對(duì)外暴露了 getConfig 方法 ,當(dāng) main 線程初始化 SimpleConfig 對(duì)象之后,當(dāng)其他線程調(diào)用  getConfig 方法時(shí),因?yàn)橹挥凶x,沒(méi)有寫操作,所以是線程安全的。HM728資訊網(wǎng)——每日最新資訊28at.com

3.讀寫鎖:讀讀不互斥,讀寫互斥,寫寫互斥

讀寫鎖是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個(gè)線程同時(shí)獲得,而寫鎖則是互斥鎖。HM728資訊網(wǎng)——每日最新資訊28at.com

它的規(guī)則是:讀讀不互斥,讀寫互斥,寫寫互斥,適用于讀多寫少的業(yè)務(wù)場(chǎng)景。HM728資訊網(wǎng)——每日最新資訊28at.com

我們一般都使用 ReentrantReadWriteLock ,該類實(shí)現(xiàn)了 ReadWriteLock 。ReadWriteLock 接口也很簡(jiǎn)單,其內(nèi)部主要提供了兩個(gè)方法,分別返回讀鎖和寫鎖 。HM728資訊網(wǎng)——每日最新資訊28at.com

public interface ReadWriteLock {    //獲取讀鎖    Lock readLock();    //獲取寫鎖    Lock writeLock();}

讀寫鎖的使用方式如下所示:HM728資訊網(wǎng)——每日最新資訊28at.com

  1. 創(chuàng)建 ReentrantReadWriteLock 對(duì)象 , 當(dāng)使用 ReadWriteLock 的時(shí)候,并不是直接使用,而是獲得其內(nèi)部的讀鎖和寫鎖,然后分別調(diào)用 lock / unlock 方法 ;
private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
  1. 讀取共享數(shù)據(jù) ;
Lock readLock = readWriteLock.readLock();readLock.lock();try {   // TODO 查詢共享數(shù)據(jù)} finally {   readLock.unlock();}
  1. 寫入共享數(shù)據(jù);
Lock writeLock = readWriteLock.writeLock();writeLock.lock();try {   // TODO 修改共享數(shù)據(jù)} finally {   writeLock.unlock();}

下面的代碼展示如何使用 ReadWriteLock 線程安全的使用 HashMap :HM728資訊網(wǎng)——每日最新資訊28at.com

import java.util.HashMap;import java.util.Map;import java.util.concurrent.locks.ReadWriteLock;import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockCache {      // 創(chuàng)建一個(gè) HashMap 來(lái)存儲(chǔ)緩存的數(shù)據(jù)    private Map<String, String> map = new HashMap<>();    // 創(chuàng)建讀寫鎖對(duì)象    private ReadWriteLock rw = new ReentrantReadWriteLock();    // 放對(duì)象方法:向緩存中添加一個(gè)鍵值對(duì)    public void put(String key, String value) {        // 獲取寫鎖,以確保當(dāng)前操作是獨(dú)占的        rw.writeLock().lock();        try {            // 執(zhí)行寫操作,將鍵值對(duì)放入 map            map.put(key, value);        } finally {            // 釋放寫鎖            rw.writeLock().unlock();        }    }    // 取對(duì)象方法:從緩存中獲取一個(gè)值    public String get(String key) {        // 獲取讀鎖,允許并發(fā)讀操作        rw.readLock().lock();        try {            // 執(zhí)行讀操作,從 map 中獲取值            return map.get(key);        } finally {            // 釋放讀鎖            rw.readLock().unlock();        }    }}

使用讀寫鎖操作 HashMap 是一個(gè)非常經(jīng)典的技巧,消息中間件 RockeMQ NameServer (名字服務(wù))保存和查詢路由信息都是通過(guò)這種技巧實(shí)現(xiàn)的。HM728資訊網(wǎng)——每日最新資訊28at.com

另外,讀寫鎖可以操作多個(gè) HashMap ,相比 ConcurrentHashMap 而言,ReadWriteLock 可以控制緩存對(duì)象的顆粒度,具備更大的靈活性。HM728資訊網(wǎng)——每日最新資訊28at.com

4.Collections.synchronizedMap : 讀寫均加鎖

如下代碼,當(dāng)我們多線程使用 userMap 時(shí),HM728資訊網(wǎng)——每日最新資訊28at.com

static Map<Long, User> userMap = Collections.synchronizedMap(new HashMap<Long, User>());

進(jìn)入 synchronizedMap 方法:HM728資訊網(wǎng)——每日最新資訊28at.com

public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {       return new SynchronizedMap<>(m);}

圖片圖片HM728資訊網(wǎng)——每日最新資訊28at.com

SynchronizedMap 內(nèi)部包含一個(gè)對(duì)象鎖 Object mutex ,它本質(zhì)上是一個(gè)包裝類,將 HashMap 的讀寫操作重新實(shí)現(xiàn)了一次,我們看到每次讀寫時(shí),都會(huì)用 synchronized 關(guān)鍵字來(lái)保證操作的線程安全。HM728資訊網(wǎng)——每日最新資訊28at.com

雖然 Collections.synchronizedMap 這種技巧使用起來(lái)非常簡(jiǎn)單,但是我們需要理解它的每次讀寫都會(huì)加鎖,性能并不會(huì)特別好。HM728資訊網(wǎng)——每日最新資訊28at.com

5.總結(jié)

這篇文章,筆者總結(jié)了四種線程安全的使用 HashMap 的技巧。HM728資訊網(wǎng)——每日最新資訊28at.com

1)方法內(nèi)部:每個(gè)線程創(chuàng)建單獨(dú)的 HashMapHM728資訊網(wǎng)——每日最新資訊28at.com

這是我們使用最普遍,也是非常可靠的方式。每個(gè)線程在方法體內(nèi)部創(chuàng)建HashMap 實(shí)例,在多線程環(huán)境下,不需要對(duì) HashMap 進(jìn)行任何同步操作。HM728資訊網(wǎng)——每日最新資訊28at.com

2) 配置數(shù)據(jù):初始化單線程寫,后續(xù)只提供讀HM728資訊網(wǎng)——每日最新資訊28at.com

中間件在啟動(dòng)時(shí),會(huì)讀取配置文件,將配置數(shù)據(jù)寫入到 HashMap 中,主線程寫完之后,以后不會(huì)再有寫入操作,其他的線程可以讀取,不會(huì)產(chǎn)生線程安全問(wèn)題。HM728資訊網(wǎng)——每日最新資訊28at.com

3)讀寫鎖:讀讀不互斥,讀寫互斥,寫寫互斥HM728資訊網(wǎng)——每日最新資訊28at.com

讀寫鎖是一把鎖分為兩部分:讀鎖和寫鎖,其中讀鎖允許多個(gè)線程同時(shí)獲得,而寫鎖則是互斥鎖。HM728資訊網(wǎng)——每日最新資訊28at.com

它的規(guī)則是:讀讀不互斥,讀寫互斥,寫寫互斥,適用于讀多寫少的業(yè)務(wù)場(chǎng)景。HM728資訊網(wǎng)——每日最新資訊28at.com

使用讀寫鎖操作 HashMap 是一個(gè)非常經(jīng)典的技巧,消息中間件 RockeMQ NameServer (名字服務(wù))保存和查詢路由信息都是通過(guò)這種技巧實(shí)現(xiàn)的。HM728資訊網(wǎng)——每日最新資訊28at.com

4)Collections.synchronizedMap  : 讀寫均加鎖HM728資訊網(wǎng)——每日最新資訊28at.com

Collections.synchronizedMap 方法使用了裝飾器模式為線程不安全的 HashMap 提供了一個(gè)線程安全的裝飾器類 SynchronizedMap。HM728資訊網(wǎng)——每日最新資訊28at.com

通過(guò) SynchronizedMap 來(lái)間接的保證對(duì) HashMap 的操作是線程安全,而 SynchronizedMap 底層也是通過(guò) synchronized 關(guān)鍵字來(lái)保證操作的線程安全。HM728資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.tebozhan.com/showinfo-26-92144-0.html如何線程安全的使用 HashMap

聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com

上一篇: 2024 年你可以使用的十大 Node.js 現(xiàn)代特性

下一篇: 好坑,流水號(hào)重復(fù)竟然導(dǎo)致了一次生產(chǎn)事故!

標(biāo)簽:
  • 熱門焦點(diǎn)
  • 盧偉冰長(zhǎng)文解析K60至尊版 對(duì)Redmi有著里程碑式的意義

    在今天的Redmi后性能時(shí)代戰(zhàn)略發(fā)布會(huì)結(jié)束之后,Redmi總經(jīng)理盧偉冰又帶來(lái)了一篇長(zhǎng)文,詳解了為什么 Redmi 要開啟后性能時(shí)代?為什么選擇和 MediaTek、Pixelworks 深度合作?以及后性
  • 石頭智能洗地機(jī)A10 Plus體驗(yàn):雙向自清潔治好了我的懶癌

    一、前言和介紹專為家庭請(qǐng)假懶人而生的石頭科技在近日又帶來(lái)了自己的全新旗艦新品,石頭智能洗地機(jī)A10 Plus。從這個(gè)產(chǎn)品名上就不難看出,這次石頭推出的并不是常見的掃地機(jī)器
  • 5月iOS設(shè)備性能榜:M1 M2依舊是榜單前五

    和上個(gè)月一樣,沒(méi)有新品發(fā)布的iOS設(shè)備性能榜的上榜設(shè)備并沒(méi)有什么更替,僅僅只有跑分變化而產(chǎn)生的排名變動(dòng),剛剛開始的蘋果WWDC2023,推出的產(chǎn)品也依舊是新款Mac Pro、新款Mac Stu
  • 從 Pulsar Client 的原理到它的監(jiān)控面板

    背景前段時(shí)間業(yè)務(wù)團(tuán)隊(duì)偶爾會(huì)碰到一些 Pulsar 使用的問(wèn)題,比如消息阻塞不消費(fèi)了、生產(chǎn)者消息發(fā)送緩慢等各種問(wèn)題。雖然我們有個(gè)監(jiān)控頁(yè)面可以根據(jù) topic 維度查看他的發(fā)送狀態(tài),
  • 一文搞定Java NIO,以及各種奇葩流

    大家好,我是哪吒。很多朋友問(wèn)我,如何才能學(xué)好IO流,對(duì)各種流的概念,云里霧里的,不求甚解。用到的時(shí)候,現(xiàn)百度,功能雖然實(shí)現(xiàn)了,但是為什么用這個(gè)?不知道。更別說(shuō)效率問(wèn)題了~下次再遇到,
  • 共享單車的故事講到哪了?

    來(lái)源丨海克財(cái)經(jīng)與共享充電寶相差不多,共享單車已很久沒(méi)有被國(guó)內(nèi)熱點(diǎn)新聞關(guān)照到了。除了一再漲價(jià)和用戶直呼用不起了。近日多家媒體再發(fā)報(bào)道稱,成都、天津、鄭州等地多個(gè)共享單
  • 網(wǎng)紅炒股不為了賺錢,那就是耍流氓!

    來(lái)源:首席商業(yè)評(píng)論6月26日高調(diào)宣布入市,網(wǎng)絡(luò)名嘴大v胡錫進(jìn)居然進(jìn)軍了股市。在一次財(cái)經(jīng)媒體峰會(huì)上,幾個(gè)財(cái)經(jīng)圈媒體大佬就&ldquo;胡錫進(jìn)炒股是否知道認(rèn)真報(bào)道&rdquo;展開討論。有
  • iQOO 11S屏幕細(xì)節(jié)公布:首發(fā)三星2K E6全感屏 安卓最好的直屏手機(jī)

    日前iQOO手機(jī)官方宣布,新一代電競(jìng)旗艦iQOO 11S將會(huì)在7月4日19:00正式與大家見面。隨著發(fā)布時(shí)間的日益臨近,官方關(guān)于該機(jī)的預(yù)熱也更加密集,截至目前已
  • Windows 11發(fā)布,微軟一改往常對(duì)老機(jī)型開放的態(tài)度

    距離 Windows 11 發(fā)布已經(jīng)過(guò)去一周,在過(guò)去一周里,很多數(shù)碼愛(ài)好者圍繞其對(duì) Android 應(yīng)用的支持、對(duì)老機(jī)型的升級(jí)問(wèn)題展開了激烈討論。與以往不同的是,在這次大
Top