最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java高并發(fā)下鎖的優(yōu)化詳解

 更新時(shí)間:2024年01月10日 09:38:17   作者:愛coding的同學(xué)  
這篇文章主要介紹了Java高并發(fā)下鎖的優(yōu)化詳解,鎖是最常用的同步方法之一,在高并發(fā)的環(huán)境下,激烈的鎖競爭會(huì)導(dǎo)致程序的性能下降,下面是一些關(guān)于鎖的使用建議,可以把這種副作用降到最低,需要的朋友可以參考下

簡述

鎖是最常用的同步方法之一。在高并發(fā)的環(huán)境下,激烈的鎖競爭會(huì)導(dǎo)致程序的性能下降。

下面是一些關(guān)于鎖的使用建議,可以把這種副作用降到最低。

減少鎖持有時(shí)間

對(duì)于使用鎖進(jìn)行并發(fā)控制的應(yīng)用程序而言,在鎖競爭過程中,單個(gè)線程對(duì)鎖的持有時(shí)間與系統(tǒng)性能有著直接的關(guān)系。

如果線程持有鎖的時(shí)間很長,那么相對(duì)地,鎖的競爭程序也就越激烈。

應(yīng)該盡可能地減少對(duì)某個(gè)鎖的占有時(shí)間,以減少程序間互斥的可能。

public synchronized void syncMethod() {
		otherCode1();  	   //無同步控制需要
		needSynMethod();   //有同步控制需要
		otherCode2();      //無同步控制需要
	}
	
public void syncMethod2() {
		otherCode1();  	   //無同步控制需要
		synchronized(this) {
			needSynMethod();   //有同步控制需要
		}
		otherCode2();      //無同步控制需要
	}

說明:減少鎖的持有時(shí)間有助于降低鎖沖突的可能性,進(jìn)而提升系統(tǒng)的并發(fā)能力。

減少鎖粒度

減少鎖粒度也是一種削弱多線程鎖競爭的有效手段。這種技術(shù)典型的使用場景就是ConcurrentHashMap類的實(shí)現(xiàn)。ConcurrentHashMap和Hashtable主要區(qū)別就是圍繞著鎖的粒度以及如何鎖,可以簡單理解成把一個(gè)大的HashTable分解成多個(gè),形成了鎖分離。而Hashtable的實(shí)現(xiàn)方式是—鎖整個(gè)hash表。concurrentHashMap內(nèi)部細(xì)分了若干個(gè)小的hashMap,稱之為段(segment),默認(rèn)情況下,被細(xì)分為16個(gè)段。新增的時(shí)候根據(jù)key的hashcode計(jì)算出應(yīng)該存放到哪一個(gè)段中,然后對(duì)這個(gè)段枷鎖,完成put()操作。就是說,最多可以同時(shí)接收16個(gè)線程同時(shí)插入(前提是16個(gè)不同段插入),從而大大提高吞吐量。但是,減少鎖粒度會(huì)引入一個(gè)新的問題,即:當(dāng)系統(tǒng)需要取得全局鎖時(shí),其消耗的資源會(huì)比較多。需要遍歷每一個(gè)段,對(duì)每一個(gè)段進(jìn)行加鎖,最后還要對(duì)每一個(gè)段進(jìn)行解鎖。concurrentHashMap的size()方法會(huì)先使用無鎖的方式求和,如果失敗才會(huì)嘗試這種加鎖的方法。所以,在高并發(fā)場合,size()的性能差于同步的Hashmap,適用于size()調(diào)用少的場合。 說明:所謂減少鎖粒度,就是指縮小鎖定對(duì)象的范圍,從而減少鎖沖突的可能性,進(jìn)行提供系統(tǒng)的并發(fā)能力。

讀寫分離鎖來替換獨(dú)占鎖

ReadWriteLock讀寫分離鎖替代獨(dú)占鎖是減少鎖粒度的一種特殊情況。減少鎖粒度是通過分割數(shù)據(jù)結(jié)構(gòu)來實(shí)現(xiàn)的,而讀寫鎖則是對(duì)系統(tǒng)功能點(diǎn)的分割。 讀操作本身不會(huì)影響數(shù)據(jù)的完整性和一致性。因此,理論上講,在大部分情況下,應(yīng)該可以允許多想成同時(shí)讀。 讀寫鎖的訪問約束情況:讀-讀(非阻塞)、讀-寫(阻塞)、寫-讀(阻塞)、寫-寫(阻塞)

public class ReadWriteLockTest2 {
         public static void main(String[] args) {
             //創(chuàng)建一個(gè)鎖對(duì)象
             ReadWriteLock lock = new ReentrantReadWriteLock(false);
             //創(chuàng)建一個(gè)線程池
             ExecutorService pool = Executors.newFixedThreadPool(2);
             //創(chuàng)建一些并發(fā)訪問
             RWRun rw1 = new RWRun(lock,true);
             RWRun rw2 = new RWRun(lock,true);
             RWRun rw3 = new RWRun(lock,false);
             //在線程池中執(zhí)行各個(gè)的操作
             pool.execute(rw1);
             pool.execute(rw2);
             pool.execute(rw3);
             //關(guān)閉線程池
             pool.shutdown();
         }
}
class RWRun implements Runnable {
         private ReadWriteLock myLock;                 //執(zhí)行操作所需的鎖對(duì)象
         private boolean ischeck;         //是否查詢
         public RWRun(ReadWriteLock myLock, boolean ischeck) {
			super();
			this.myLock = myLock;
			this.ischeck = ischeck;
		}
		public void run() {
                 if (ischeck) {
                         //獲取讀鎖
                         myLock.readLock().lock();
                         try {
							Thread.sleep(1000);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
                         //釋放讀鎖
                         myLock.readLock().unlock();
                 } else {
                         //獲取寫鎖
                         myLock.writeLock().lock();
                         try {
 							Thread.sleep(1000);
 						} catch (InterruptedException e) {
 							e.printStackTrace();
 						}
                         //釋放寫鎖
                         myLock.writeLock().unlock();
                 }
         }
}

上面執(zhí)行完的時(shí)間為2秒鐘,如果是獨(dú)占鎖 就需要3秒鐘 結(jié)論:在讀多寫少的場合,使用讀寫鎖可以有效提升系統(tǒng)的并發(fā)能力。

鎖分離

在LinkedBlockingQueue的實(shí)現(xiàn)中,take()和put()分別實(shí)現(xiàn)了從隊(duì)列中取得數(shù)據(jù)和往隊(duì)列中增加數(shù)據(jù)的功能。

雖然兩個(gè)函數(shù)都對(duì)當(dāng)前隊(duì)列進(jìn)行了修改操作,但由于是基于鏈表的,因此,兩個(gè)操作分別作用于隊(duì)列的前端和尾端,從理論上來說,兩者并不沖突。

所以在JDK中,采用了兩把不同的鎖,分離了toke()和put()的操作,實(shí)現(xiàn)了可并發(fā)的操作。

//take()函數(shù)需要持有的鎖
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();
//put()函數(shù)需要持有的鎖
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();

鎖粗化

虛擬機(jī)在遇到一連串連續(xù)地對(duì)同一鎖不斷進(jìn)行請(qǐng)求和釋放的操作時(shí),便會(huì)把所有的鎖操作整合成對(duì)鎖的一次請(qǐng)求,從而減少對(duì)鎖的請(qǐng)求同步次數(shù),這個(gè)操作叫做鎖的粗化。

例子:在循環(huán)內(nèi)請(qǐng)求鎖時(shí)。

   for (int i =0 i < n; i++) {
           synchronized (lock) {
		doSomething();
	   }
   }

更加合理的做法應(yīng)該是在外層只請(qǐng)求一次鎖

到此這篇關(guān)于Java高并發(fā)下鎖的優(yōu)化詳解的文章就介紹到這了,更多相關(guān)高并發(fā)下鎖的優(yōu)化內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JDK動(dòng)態(tài)代理過程原理及手寫實(shí)現(xiàn)詳解

    JDK動(dòng)態(tài)代理過程原理及手寫實(shí)現(xiàn)詳解

    這篇文章主要為大家介紹了JDK動(dòng)態(tài)代理過程原理及手寫實(shí)現(xiàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java中左移和右移問題圖文詳解

    Java中左移和右移問題圖文詳解

    左移和右移并不常用,在一些特殊情況下才會(huì)使用,比如加解密時(shí),會(huì)大量用到,這篇文章主要給大家介紹了關(guān)于Java中左移和右移問題的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • Java使用Gateway自定義負(fù)載均衡過濾器

    Java使用Gateway自定義負(fù)載均衡過濾器

    這篇文章主要介紹了Java使用Gateway自定義負(fù)載均衡過濾器,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • java實(shí)現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο?

    java實(shí)現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο?

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)學(xué)生管理系統(tǒng)(面向?qū)ο螅?,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-03-03
  • Java:com.netflix.client.ClientException錯(cuò)誤解決

    Java:com.netflix.client.ClientException錯(cuò)誤解決

    本文主要介紹了Java:com.netflix.client.ClientException錯(cuò)誤解決,主要是指出客戶端?module-sso?試圖通過負(fù)載均衡器訪問服務(wù)時(shí),負(fù)載均衡器沒有找到可用的服務(wù)器來處理請(qǐng)求,下面就來介紹一下解決方法
    2024-08-08
  • JavaSE程序邏輯控制實(shí)現(xiàn)詳細(xì)圖文教程

    JavaSE程序邏輯控制實(shí)現(xiàn)詳細(xì)圖文教程

    JavaSE是為了開發(fā)桌面應(yīng)用程序和控制臺(tái)應(yīng)用程序而設(shè)計(jì)的,使用JavaSE可以編寫?yīng)毩⑦\(yùn)行的Java應(yīng)用程序,這篇文章主要給大家介紹了關(guān)于JavaSE程序邏輯控制實(shí)現(xiàn)的相關(guān)資料,需要的朋友可以參考下
    2024-04-04
  • Springmvc ResponseBody響應(yīng)json數(shù)據(jù)實(shí)現(xiàn)過程

    Springmvc ResponseBody響應(yīng)json數(shù)據(jù)實(shí)現(xiàn)過程

    這篇文章主要介紹了Springmvc ResponseBody響應(yīng)json數(shù)據(jù)實(shí)現(xiàn)過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • IDEA將Java.class文件反編譯為Java文件原理、實(shí)踐與深度解析

    IDEA將Java.class文件反編譯為Java文件原理、實(shí)踐與深度解析

    本文詳細(xì)介紹了如何使用IntelliJ IDEA進(jìn)行.class到.java的反編譯,包括基礎(chǔ)概念、實(shí)用技巧、引擎配置、疑難問題解決以及生產(chǎn)環(huán)境實(shí)戰(zhàn)案例,通過這些步驟,開發(fā)者可以有效地理解和學(xué)習(xí)Java代碼,提升開發(fā)效率,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • 基于SpringBoot+FastExcel的百萬級(jí)數(shù)據(jù)導(dǎo)入導(dǎo)出完整方案

    基于SpringBoot+FastExcel的百萬級(jí)數(shù)據(jù)導(dǎo)入導(dǎo)出完整方案

    本文詳細(xì)介紹了在SpringBoot3.5.11+JDK17+MySQL環(huán)境下,使用FastExcel實(shí)現(xiàn)百萬級(jí)數(shù)據(jù)的導(dǎo)入和導(dǎo)出,內(nèi)容包括數(shù)據(jù)庫表設(shè)計(jì)、百萬測試數(shù)據(jù)生成、實(shí)體類與Mapper、配置文件、百萬數(shù)據(jù)導(dǎo)入、百萬數(shù)據(jù)導(dǎo)出、線程池、阻塞隊(duì)列、CountDownLatch的設(shè)計(jì)思路與原理,以及接口測試方法
    2026-03-03
  • 使用Java程序模擬實(shí)現(xiàn)新冠病毒傳染效果

    使用Java程序模擬實(shí)現(xiàn)新冠病毒傳染效果

    這篇文章主要介紹了用Java程序模擬實(shí)現(xiàn)新冠病毒傳染效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08

最新評(píng)論

华宁县| 岱山县| 富民县| 怀安县| 鄂州市| 长沙县| 彭山县| 巴里| 三原县| 堆龙德庆县| 九台市| 磴口县| 新津县| 凤城市| 乃东县| 大关县| 北辰区| 安远县| 铁力市| 贵州省| 祥云县| 双鸭山市| 甘孜县| 邵东县| 乐陵市| 扎兰屯市| 扬州市| 寻乌县| 洛宁县| 谢通门县| 南开区| 黔南| 洪雅县| 开阳县| 都昌县| 阿巴嘎旗| 铁岭市| 东城区| 孟村| 丰台区| 西林县|