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

Java中的自旋鎖與適應性自旋鎖詳解

 更新時間:2023年10月13日 09:11:02   作者:yyangjun  
這篇文章主要介紹了Java中的自旋鎖與適應性自旋鎖詳解,在多處理器環(huán)境中某些資源的有限性,有時需要互斥訪問,這時候就需要引入鎖的概念,只有獲取了鎖的線程才能對資源進行訪問,多線程的核心是CPU的時間分片,所以同一時刻只能有一個線程獲取到鎖,需要的朋友可以參考下

一、為什么需要自旋鎖與適應性自旋鎖

1.1、自旋鎖的提出背景

由于在多處理器環(huán)境中某些資源的有限性,有時需要互斥訪問,這時候就需要引入鎖的概念,只有獲取了鎖的線程才能對資源進行訪問,由于多線程的核心是CPU的時間分片,所以同一時刻只能有一個線程獲取到鎖。那么就面臨一個問題,那么沒有獲取到鎖的線程應該怎么辦?

通常有兩種處理方式:

  1. 一種是沒有獲取到鎖的線程就一直循環(huán)等待判斷該資源是否已經(jīng)釋放鎖,這種鎖叫做自旋鎖,它不用將線程阻塞起來(NON-BLOCKING);
  2. 還有一種處理方式就是把自己阻塞起來,等待重新調(diào)度請求,這種叫做互斥鎖。

使用自旋鎖的最大的一個好處是因為自旋鎖存在于linux內(nèi)核中,如果持有鎖的線程能夠在短時間內(nèi)釋放鎖,那么那些等待競爭鎖的線程就不需要做內(nèi)核態(tài)與用戶態(tài)之間的切換從而進入阻塞狀態(tài)。

二、自旋鎖與適應性自旋鎖底層原理解析

2.1、自旋鎖與適應性自旋鎖底層原理解析

自旋鎖早在JDK1.4 中就引入了,只是當時默認時關閉的。在JDK 1.6后默認為開啟狀態(tài)。自旋鎖本質上與阻塞并不相同,先不考慮其對多處理器的要求,如果鎖占用的時間非常的短,那么自旋鎖的性能會非常的好,相反,其會帶來更多的性能開銷(因為在線程自旋時,始終會占用CPU的時間片,如果鎖占用的時間太長,那么自旋的線程會白白消耗掉CPU資源)。

因此自旋等待的時間必須要有一定的限度,如果自旋超過了限定的次數(shù)仍然沒有成功獲取到鎖,就應該使用傳統(tǒng)的方式去掛起線程了,在JDK定義中,自旋鎖默認的自旋次數(shù)為10次,用戶可以使用參數(shù)-XX:PreBlockSpin來更改。

可是現(xiàn)在又出現(xiàn)了一個問題:如果線程鎖在線程自旋剛結束就釋放掉了鎖,那么是不是有點得不償失。所以這時候我們需要更加聰明的鎖來實現(xiàn)更加靈活的自旋。來提高并發(fā)的性能。(這里則需要自適應自旋鎖!) 在JDK 1.6中引入了自適應自旋鎖。

這就意味著自旋的時間不再固定了,而是由前一次在同一個鎖上的自旋 時間及鎖的擁有者的狀態(tài)來決定的。如果在同一個鎖對象上,自旋等待剛剛成功獲取過鎖,并且持有鎖的線程正在運行中,那么JVM會認為該鎖自旋獲取到鎖的可能性很大,會自動增加等待時間。比如增加到100此循環(huán)。相反,如果對于某個鎖,自旋很少成功獲取鎖。

那再以后要獲取這個鎖時將可能省略掉自旋過程,以避免浪費處理器資源。有了自適應自旋,JVM對程序的鎖的狀態(tài)預測會越來越準確,JVM也會越來越聰明。

三、自旋鎖與適應性自旋鎖的使用

3.1、自旋鎖的實現(xiàn)

public class SpinLockTest {
	private AtomicBoolean available =new AtomicBoolean(false);
	public void lock(){
	    //循環(huán)檢測嘗試獲取鎖
	    while(!tryLock()){
	    //doSomething...
	    }
	}
    public boolean tryLock(){
    	//嘗試獲取鎖,成功返回true,失敗返回false
    	return available.compareAndSet(false,true);
    }
    public void unLock(){
    	if(!available.compareAndSet(false,true)){
    		throw new RuntimeException("釋放鎖失敗");
    	}
    }
}

3.2、適應性自旋鎖的實現(xiàn)

自旋等待雖然避免了線程切換的開銷,但它要占用處理器時間。如果鎖被占用的時間很短,自旋等待的效果就會非常好。反之,如果鎖被占用的時間很長,那么自旋的線程只會白浪費處理器資源。所以,自旋等待的時間必須要有一定的限度,如果自旋超過了限定次數(shù)(默認是10次,可以使用-XX:PreBlockSpin來更改)沒有成功獲得鎖,就應當掛起線程。

自旋鎖的實現(xiàn)原理同樣也是CAS,AtomicInteger中調(diào)用unsafe進行自增操作的源碼中的do-while循環(huán)就是一個自旋操作,如果修改數(shù)值失敗則通過循環(huán)來執(zhí)行自旋,直至修改成功。 改進的自旋鎖主要有TicketLock、CLHLock、MCSLock,這幾種自旋鎖改進方案內(nèi)容比較多,實現(xiàn)方式參考 幾種自旋鎖的java實現(xiàn)824b2e4f1eed

四、自旋鎖與適應性自旋鎖中存在的問題與優(yōu)化方案

自旋鎖盡可能的減少線程的阻塞,這對于鎖的競爭不激烈,且占用鎖時間非常短的代碼塊來說性能可以大幅度提升,因為自旋的消耗會小于線程阻塞掛起再喚醒的操作的消耗,這些操作會導致線程發(fā)生兩次上下文切換!

但是如果鎖的競爭激烈,或者持有鎖的線程需要長時間占用鎖執(zhí)行同步塊,這時候就不適合使用自旋鎖了,因為自旋鎖在獲取鎖前一直都是占用cpu做無用功,同時有大量線程在競爭一個鎖,會導致獲取鎖的時間很長,線程自旋的消耗大于線程阻塞掛起操作的消耗,其它需要cup的線程又不能獲取到cpu,造成 cpu的浪費。所以這種情況下我們要關閉自旋鎖;自旋鎖時間閾值(1.6 引入了適應性自旋鎖)。

自旋鎖的目的是為了占著CPU的資源不釋放,等到獲取到鎖立即進行處理。但是如何去選擇自旋的執(zhí)行時間呢?如果自旋執(zhí)行時間太長,會有大量的線程處于自旋狀態(tài)占用CPU資源,進而會影響整體系統(tǒng)的性能。因此自旋的周期選的額外重要!

JVM 對于自旋周期的選擇,Jdk1.5這個限度是一定的寫死的,在1.6引入了適應性自旋鎖,適應性自旋鎖意味著自旋的時間不在是固定的了,而是由前一次在同一個鎖上的自旋時間以及鎖的擁有者的狀態(tài)來決定,基本認為一個線程上下文切換的時間是最佳的一個時間,同時JVM還針對當前CPU的負荷情況做了較多的優(yōu)化,如果平均負載小于CPUs則一直自旋,如果有超過(CPUs/2)個線程正在自旋,則后來線程直接阻塞,如果正在自旋的線程發(fā)現(xiàn)Owner發(fā)生了變化則延遲自旋時間(自旋計數(shù))或進入阻塞,如果 CPU 處于節(jié)電模式則停止自旋,自旋時間的最壞情況是CPU的存儲延遲(CPU A 存儲了一個數(shù)據(jù),到CPU B得知這個數(shù)據(jù)直接的時間差),自旋時會適當放棄線程優(yōu)先級之間的差異。

到此這篇關于Java中的自旋鎖與適應性自旋鎖詳解的文章就介紹到這了,更多相關Java中的自旋鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Spring循環(huán)依賴產(chǎn)生與解決

    Spring循環(huán)依賴產(chǎn)生與解決

    Spring的解決循環(huán)依賴是有前置條件的,要解決循環(huán)依賴我們首先要了解Spring Bean對象的創(chuàng)建過程和依賴注入的方式。依賴注入方式,我之前的博客有所分享,大家可以在看本篇文章之前進行一下小小的回顧
    2022-12-12
  • Java隨機生成字符串的四種方式例子

    Java隨機生成字符串的四種方式例子

    這篇文章主要給大家介紹了關于Java隨機生成字符串的四種方式,隨機數(shù)在實際中使用很廣泛,比如要隨即生成一個固定長度的字符串、數(shù)字,文中給出了詳細的代碼示例,需要的朋友可以參考下
    2023-10-10
  • Java基于裝飾者模式實現(xiàn)的染色饅頭案例詳解

    Java基于裝飾者模式實現(xiàn)的染色饅頭案例詳解

    這篇文章主要介紹了Java基于裝飾者模式實現(xiàn)的染色饅頭案例,簡單描述了裝飾者模式的概念、原理及Java使用裝飾者模式的相關實現(xiàn)步驟、操作技巧與注意事項,需要的朋友可以參考下
    2018-05-05
  • Java面向對象程序設計:抽象類,接口用法實例分析

    Java面向對象程序設計:抽象類,接口用法實例分析

    這篇文章主要介紹了Java面向對象程序設計:抽象類,接口用法,結合實例形式分析了java抽象類與接口相關概念、原理、用法與操作注意事項,需要的朋友可以參考下
    2020-04-04
  • JPA如何將查詢結果轉換為DTO對象

    JPA如何將查詢結果轉換為DTO對象

    這篇文章主要介紹了JPA如何將查詢結果轉換為DTO對象,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • MyBatis還是JPA?終于有答案了

    MyBatis還是JPA?終于有答案了

    這篇文章主要介紹了MyBatis還是JPA,中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-10-10
  • 淺析Java隨機數(shù)與定時器

    淺析Java隨機數(shù)與定時器

    本篇文章給大家分析了Java隨機數(shù)與定時器的實現(xiàn)原理以及代碼分享,有需要的讀者參考下吧。
    2018-02-02
  • Vue?+?springboot實現(xiàn)拼圖人機驗證功能

    Vue?+?springboot實現(xiàn)拼圖人機驗證功能

    本文介紹了如何使用Vue和Spring?Boot實現(xiàn)拼圖人機驗證功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2026-01-01
  • springboot如何使用vue打包過的頁面資源

    springboot如何使用vue打包過的頁面資源

    這篇文章主要介紹了springboot如何使用vue打包過的頁面資源,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • IntelliJ IDEA進行遠程調(diào)試(Remote Debugging)的操作教程

    IntelliJ IDEA進行遠程調(diào)試(Remote Debugging)的操作教程

    遠程調(diào)試(Remote Debugging)是指在本地開發(fā)環(huán)境(如 IntelliJ IDEA)中,連接并調(diào)試運行在遠程機器(如測試服務器、預發(fā)環(huán)境、生產(chǎn)服務器、Docker 容器、Kubernetes Pod 等)上的 Java 應用程序,本文給大家介紹了IntelliJ IDEA進行遠程調(diào)試的操作教程
    2025-11-11

最新評論

阿坝| 长武县| 于都县| 湖南省| 汉寿县| 洛浦县| 吐鲁番市| 红安县| 仁布县| 墨脱县| 旺苍县| 荣成市| 宜城市| 垫江县| 嵊泗县| 台中县| 翁源县| 肥东县| 舟曲县| 吉隆县| 咸丰县| 伊吾县| 临桂县| 北安市| 正安县| 长丰县| 日土县| 锡林郭勒盟| 苍南县| 白朗县| 北安市| 仁寿县| 开原市| 娄底市| 盐津县| 泗洪县| 望城县| 盐边县| 台南县| 阳泉市| 谷城县|