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

Java線程并發(fā)中常見的鎖機(jī)制詳細(xì)介紹

 更新時間:2016年05月24日 17:05:39   作者:路上有多遠(yuǎn)  
越來越多的互聯(lián)網(wǎng)企業(yè)面臨著用戶量膨脹而帶來的并發(fā)安全問題。接下來通過本文給大家介紹Java線程并發(fā)中常見的鎖機(jī)制,感興趣的朋友一起看看吧

隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,越來越多的互聯(lián)網(wǎng)企業(yè)面臨著用戶量膨脹而帶來的并發(fā)安全問題。本文著重介紹了在java并發(fā)中常見的幾種鎖機(jī)制。

1.偏向鎖

偏向鎖是JDK1.6提出來的一種鎖優(yōu)化的機(jī)制。其核心的思想是,如果程序沒有競爭,則取消之前已經(jīng)取得鎖的線程同步操作。也就是說,若某一鎖被線程獲取后,便進(jìn)入偏向模式,當(dāng)線程再次請求這個鎖時,就無需再進(jìn)行相關(guān)的同步操作了,從而節(jié)約了操作時間,如果在此之間有其他的線程進(jìn)行了鎖請求,則鎖退出偏向模式。在JVM中使用-XX:+UseBiasedLocking

package jvmProject;
import java.util.List;
import java.util.Vector;
public class Biased {
  public static List<Integer> numberList = new Vector<Integer>();
  public static void main(String[] args) {
    long begin = System.currentTimeMillis();
    int count = 0;
    int startnum = 0;
    while(count<10000000){
      numberList.add(startnum);
      startnum+=2;
      count++;    
    }
    long end = System.currentTimeMillis();
    System.out.println(end-begin);
  }
}

初始化一個Vector,往里面添加10000000個Integer對象,然后輸出時間差。以此來測試偏向鎖的性能。至于為什么要使用Vector而不使用ArrayList呢?

因?yàn)锳rrayList是線程不安全的,Vector是線程安全的。這樣說可能還不夠具體,可以翻看一下源碼吧。

Vector中的幾乎所有操作是帶有sychronized的,而ArrayList是沒有的,所以Vector是線程安全的。

接下來我們來測試一下,開啟偏向鎖和不開啟偏向鎖對程序性能的影響有多大。

配置JVM啟動(開啟偏向鎖)參數(shù)為:

配置JVM啟動(關(guān)閉偏向鎖)參數(shù)為:

Perfect!開啟偏向鎖的程序運(yùn)行時間明顯較短,開啟偏向鎖比不開啟偏向鎖,在單個線程中操作一個對象的同步方法,是有一定的優(yōu)勢的。其實(shí)也可以這樣理解,當(dāng)只有一個線程操作帶有同步方法的Vector對象的時候,此時對Vector的操作就轉(zhuǎn)變成了對ArrayList的操作。

偏向鎖在鎖競爭激烈的場合沒有太強(qiáng)的優(yōu)化效果,因?yàn)榇罅康母偁帟?dǎo)致持有鎖的線程不停地切換,鎖也很難保持在偏向模式,此時,使用偏向鎖不僅得不到性能的優(yōu)化,反而有可能降低系統(tǒng)的性能,因此,在激烈競爭的場合,可以嘗試使用

-XX:-UseBiastedLocking參數(shù)禁用偏向鎖。

2.輕量級鎖

如果偏向鎖失敗,Java虛擬機(jī)就會讓線程申請輕量級鎖,輕量級鎖在虛擬機(jī)內(nèi)部,使用一個成為BasicObjectLock的對象實(shí)現(xiàn)的,這個對象內(nèi)部由一個BasicLock對象和一個持有該鎖的Java對象指針組成。BasicObjectLock對象放置在Java棧幀中。在BasicLock對象內(nèi)部還維護(hù)著displaced_header字段,用于備份對象頭部的Mark Word.

當(dāng)一個線程持有一個對象的鎖的時候,對象頭部Mark Word信息如下

[ptr |00] locked

末尾的兩位比特為00,整個Mark Word為指向BasicLock對象的指針。由于BasicObjectLock對象在線程棧中,因此該指針必然指向持有該鎖的線程??臻g。當(dāng)需要判斷一個線程是否持有該對象時,只需要簡單地判斷對象頭的指針是否在當(dāng)前線程的棧地址范圍即可。同時,BasicLock對象的displaced_header,備份了原對象的Mark word內(nèi)容,BasicObjectLock對象的obj字段則指向持有鎖的對象頭部。

3.重量級鎖

當(dāng)輕量級鎖失敗,虛擬機(jī)就會使用重量級鎖。在使用重量級鎖的時,對象的Mark Word如下:

[ptr |10] monitor

重量級鎖在操作過程中,線程可能會被操作系統(tǒng)層面掛起,如果是這樣,線程間的切換和調(diào)用成本就會大大提高。

4.自旋鎖

自旋鎖可以使線程在沒有取得鎖的時候,不被掛起,而轉(zhuǎn)去執(zhí)行一個空循環(huán),(即所謂的自旋,就是自己執(zhí)行空循環(huán)),若在若干個空循環(huán)后,線程如果可以獲得鎖,則繼續(xù)執(zhí)行。若線程依然不能獲得鎖,才會被掛起。

使用自旋鎖后,線程被掛起的幾率相對減少,線程執(zhí)行的連貫性相對加強(qiáng)。因此,對于那些鎖競爭不是很激烈,鎖占用時間很短的并發(fā)線程,具有一定的積極意義,但對于鎖競爭激烈,單線程鎖占用很長時間的并發(fā)程序,自旋鎖在自旋等待后,往往毅然無法獲得對應(yīng)的鎖,不僅僅白白浪費(fèi)了CPU時間,最終還是免不了被掛起的操作 ,反而浪費(fèi)了系統(tǒng)的資源。

在JDK1.6中,Java虛擬機(jī)提供-XX:+UseSpinning參數(shù)來開啟自旋鎖,使用-XX:PreBlockSpin參數(shù)來設(shè)置自旋鎖等待的次數(shù)。

在JDK1.7開始,自旋鎖的參數(shù)被取消,虛擬機(jī)不再支持由用戶配置自旋鎖,自旋鎖總是會執(zhí)行,自旋鎖次數(shù)也由虛擬機(jī)自動調(diào)整。

相關(guān)文章

  • Java Socket編程實(shí)例(五)- NIO UDP實(shí)踐

    Java Socket編程實(shí)例(五)- NIO UDP實(shí)踐

    這篇文章主要講解Java Socket編程中NIO UDP的實(shí)例,希望能給大家做一個參考。
    2016-06-06
  • 詳解Java8?StreamAPI中的map()方法

    詳解Java8?StreamAPI中的map()方法

    Stream?API?是Java8中新加入的功能,這篇文章主要帶大家了解一下?Stream?API?中的?map()?方法的使用,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2023-04-04
  • 關(guān)于Java中避免空指針的方法

    關(guān)于Java中避免空指針的方法

    這篇文章主要介紹了關(guān)于Java中避免空指針的方法,空指針異常就是我們在對空對象進(jìn)行的任何操作都會報空指針異常,所謂的指針,就是java中的對象的引用,比如String?s;這個就是指針,需要的朋友可以參考下
    2023-07-07
  • mybatis向數(shù)據(jù)庫里插入記錄后自動返回記錄ID問題

    mybatis向數(shù)據(jù)庫里插入記錄后自動返回記錄ID問題

    本文介紹了在接手項目時,對一個業(yè)務(wù)處理邏輯進(jìn)行重構(gòu)和性能優(yōu)化的經(jīng)歷,作者提到,性能問題可能是導(dǎo)致bug的一個重要原因,作者提到,在以前的.NET項目中,插入記錄后系統(tǒng)會自動刷新實(shí)體類,為其中的主鍵ID賦值,而SpringBoot項目mybatis也可以通過指定主鍵來優(yōu)化代碼
    2025-01-01
  • JAVA圖形界面(GUI)之表格的示例代碼

    JAVA圖形界面(GUI)之表格的示例代碼

    這篇文章主要介紹了JAVA圖形界面(GUI)之表格的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作

    Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作

    這篇文章主要介紹了Java引用傳遞和值傳遞棧內(nèi)存與堆內(nèi)存的指向操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • 教你怎么用Java通過關(guān)鍵字修改pdf

    教你怎么用Java通過關(guān)鍵字修改pdf

    此方法只適合通過關(guān)鍵字位置,在pdf上添加字符直接上代碼,代碼比較長,大部分自己的理解都在代碼注釋中了,需要的朋友可以參考下
    2021-05-05
  • Java PhantomJs完成html圖片輸出功能

    Java PhantomJs完成html圖片輸出功能

    給大家?guī)硪黄P(guān)于用Java PhantomJs完成html圖片輸出功能的教學(xué)內(nèi)容,有興趣的朋友學(xué)習(xí)參考下吧。
    2017-12-12
  • Java預(yù)覽PDF時的文件名稱問題及解決

    Java預(yù)覽PDF時的文件名稱問題及解決

    這篇文章主要介紹了Java預(yù)覽PDF時的文件名稱問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java 過濾器filter防sql注入的實(shí)現(xiàn)代碼

    java 過濾器filter防sql注入的實(shí)現(xiàn)代碼

    下面小編就為大家?guī)硪黄猨ava 過濾器filter防sql注入的實(shí)現(xiàn)代碼。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08

最新評論

平顶山市| 铁岭县| 静安区| 绥阳县| 武陟县| 蒙山县| 金湖县| 蓬莱市| 杭锦后旗| 宜兰县| 仁布县| 工布江达县| 红河县| 六枝特区| 大城县| 商城县| 章丘市| 大洼县| 辽阳县| 色达县| 永平县| 高密市| 绥阳县| 嵊泗县| 墨竹工卡县| 应用必备| 拜泉县| 定日县| 红安县| 兰溪市| 大邑县| 定襄县| 盘锦市| 磐石市| 高邮市| 咸宁市| 黄石市| 萍乡市| 高淳县| 济阳县| 昌黎县|