日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java多线程系列(四):4种常用Java线程锁的特点,性能比较、使用场景

發(fā)布時(shí)間:2024/7/5 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java多线程系列(四):4种常用Java线程锁的特点,性能比较、使用场景 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.



多線程的緣由

在出現(xiàn)了進(jìn)程之后,操作系統(tǒng)的性能得到了大大的提升。雖然進(jìn)程的出現(xiàn)解決了操作系統(tǒng)的并發(fā)問(wèn)題,但是人們?nèi)匀徊粷M足,人們逐漸對(duì)實(shí)時(shí)性有了要求。

使用多線程的理由之一是和進(jìn)程相比,它是一種非常花銷小,切換快,更”節(jié)儉”的多任務(wù)操作方式。


在Linux系統(tǒng)下,啟動(dòng)一個(gè)新的進(jìn)程必須分配給它獨(dú)立的地址空間,建立眾多的數(shù)據(jù)表來(lái)維護(hù)它的代碼段、堆棧段和數(shù)據(jù)段,這是一種”昂貴”的多任務(wù)工作方式。而在進(jìn)程中的同時(shí)運(yùn)行多個(gè)線程,它們彼此之間使用相同的地址空間,共享大部分?jǐn)?shù)據(jù),啟動(dòng)一個(gè)線程所花費(fèi)的空間遠(yuǎn)遠(yuǎn)小于啟動(dòng)一個(gè)進(jìn)程所花費(fèi)的空間,而且,線程間彼此切換所需的時(shí)間也遠(yuǎn)遠(yuǎn)小于進(jìn)程間切換所需要的時(shí)間。

多線程并發(fā)面臨的問(wèn)題

由于多個(gè)線程是共同占有所屬進(jìn)程的資源和地址空間的,那么就會(huì)存在一個(gè)問(wèn)題:

如果多個(gè)線程要同時(shí)訪問(wèn)某個(gè)資源,怎么處理?

在Java并發(fā)編程中,經(jīng)常遇到多個(gè)線程訪問(wèn)同一個(gè) 共享資源 ,這時(shí)候作為開(kāi)發(fā)者必須考慮如何維護(hù)數(shù)據(jù)一致性,這就是Java鎖機(jī)制(同步問(wèn)題)的來(lái)源。


Java提供了多種多線程鎖機(jī)制的實(shí)現(xiàn)方式,常見(jiàn)的有:

  • synchronized
  • ReentrantLock
  • Semaphore
  • AtomicInteger等
  • 每種機(jī)制都有優(yōu)缺點(diǎn)與各自的適用場(chǎng)景,必須熟練掌握他們的特點(diǎn)才能在Java多線程應(yīng)用開(kāi)發(fā)時(shí)得心應(yīng)手。

    4種Java線程鎖(線程同步)


    1.synchronized


    在Java中synchronized關(guān)鍵字被常用于維護(hù)數(shù)據(jù)一致性。


    synchronized機(jī)制是給共享資源上鎖,只有拿到鎖的線程才可以訪問(wèn)共享資源,這樣就可以強(qiáng)制使得對(duì)共享資源的訪問(wèn)都是順序的。

    Java開(kāi)發(fā)人員都認(rèn)識(shí)synchronized,使用它來(lái)實(shí)現(xiàn)多線程的同步操作是非常簡(jiǎn)單的,只要在需要同步的對(duì)方的方法、類或代碼塊中加入該關(guān)鍵字,它能夠保證在同一個(gè)時(shí)刻最多只有一個(gè)線程執(zhí)行同一個(gè)對(duì)象的同步代碼,可保證修飾的代碼在執(zhí)行過(guò)程中不會(huì)被其他線程干擾。使用synchronized修飾的代碼具有原子性和可見(jiàn)性,在需要進(jìn)程同步的程序中使用的頻率非常高,可以滿足一般的進(jìn)程同步要求。

    synchronized (obj) {

    //方法

    …….

    }

    synchronized實(shí)現(xiàn)的機(jī)理依賴于軟件層面上的JVM,因此其性能會(huì)隨著Java版本的不斷升級(jí)而提高。

    到了Java1.6,synchronized進(jìn)行了很多的優(yōu)化,有適應(yīng)自旋、鎖消除、鎖粗化、輕量級(jí)鎖及偏向鎖等,效率有了本質(zhì)上的提高。在之后推出的Java1.7與1.8中,均對(duì)該關(guān)鍵字的實(shí)現(xiàn)機(jī)理做了優(yōu)化。


    需要說(shuō)明的是,當(dāng)線程通過(guò)synchronized等待鎖時(shí)是不能被Thread.interrupt()中斷的,因此程序設(shè)計(jì)時(shí)必須檢查確保合理,否則可能會(huì)造成線程死鎖的尷尬境地。


    最后,盡管Java實(shí)現(xiàn)的鎖機(jī)制有很多種,并且有些鎖機(jī)制性能也比synchronized高,但還是強(qiáng)烈推薦在多線程應(yīng)用程序中使用該關(guān)鍵字,因?yàn)閷?shí)現(xiàn)方便,后續(xù)工作由JVM來(lái)完成,可靠性高。只有在確定鎖機(jī)制是當(dāng)前多線程程序的性能瓶頸時(shí),才考慮使用其他機(jī)制,如ReentrantLock等。


    2.ReentrantLock

    可重入鎖,顧名思義,這個(gè)鎖可以被線程多次重復(fù)進(jìn)入進(jìn)行獲取操作。

    ReentantLock繼承接口Lock并實(shí)現(xiàn)了接口中定義的方法,除了能完成synchronized所能完成的所有工作外,還提供了諸如可響應(yīng)中斷鎖、可輪詢鎖請(qǐng)求、定時(shí)鎖等避免多線程死鎖的方法。


    Lock實(shí)現(xiàn)的機(jī)理依賴于特殊的CPU指定,可以認(rèn)為不受JVM的約束,并可以通過(guò)其他語(yǔ)言平臺(tái)來(lái)完成底層的實(shí)現(xiàn)。在并發(fā)量較小的多線程應(yīng)用程序中,ReentrantLock與synchronized性能相差無(wú)幾,但在高并發(fā)量的條件下,synchronized性能會(huì)迅速下降幾十倍,而ReentrantLock的性能卻能依然維持一個(gè)水準(zhǔn)。

    因此我們建議在高并發(fā)量情況下使用ReentrantLock。


    ReentrantLock引入兩個(gè)概念:公平鎖與非公平鎖


    公平鎖指的是鎖的分配機(jī)制是公平的,通常先對(duì)鎖提出獲取請(qǐng)求的線程會(huì)先被分配到鎖。反之,JVM按隨機(jī)、就近原則分配鎖的機(jī)制則稱為不公平鎖。

    ReentrantLock在構(gòu)造函數(shù)中提供了是否公平鎖的初始化方式,默認(rèn)為非公平鎖。這是因?yàn)?#xff0c;非公平鎖實(shí)際執(zhí)行的效率要遠(yuǎn)遠(yuǎn)超出公平鎖,除非程序有特殊需要,否則最常用非公平鎖的分配機(jī)制。

    ReentrantLock通過(guò)方法lock()與unlock()來(lái)進(jìn)行加鎖與解鎖操作,與synchronized會(huì)被JVM自動(dòng)解鎖機(jī)制不同,ReentrantLock加鎖后需要手動(dòng)進(jìn)行解鎖。為了避免程序出現(xiàn)異常而無(wú)法正常解鎖的情況,使用ReentrantLock必須在finally控制塊中進(jìn)行解鎖操作。通常使用方式如下所示:

    Lock lock = new ReentrantLock();

    try {

    lock.lock();

    //…進(jìn)行任務(wù)操作5 }

    finally {

    lock.unlock();

    }


    3.Semaphore

    上述兩種鎖機(jī)制類型都是“互斥鎖”,學(xué)過(guò)操作系統(tǒng)的都知道,互斥是進(jìn)程同步關(guān)系的一種特殊情況,相當(dāng)于只存在一個(gè)臨界資源,因此同時(shí)最多只能給一個(gè)線程提供服務(wù)。但是,在實(shí)際復(fù)雜的多線程應(yīng)用程序中,可能存在多個(gè)臨界資源,這時(shí)候我們可以借助Semaphore信號(hào)量來(lái)完成多個(gè)臨界資源的訪問(wèn)。

    Semaphore基本能完成ReentrantLock的所有工作,使用方法也與之類似,通過(guò)acquire()與release()方法來(lái)獲得和釋放臨界資源。

    經(jīng)實(shí)測(cè),Semaphone.acquire()方法默認(rèn)為可響應(yīng)中斷鎖,與ReentrantLock.lockInterruptibly()作用效果一致,也就是說(shuō)在等待臨界資源的過(guò)程中可以被Thread.interrupt()方法中斷。

    此外,Semaphore也實(shí)現(xiàn)了可輪詢的鎖請(qǐng)求與定時(shí)鎖的功能,除了方法名tryAcquire與tryLock不同,其使用方法與ReentrantLock幾乎一致。Semaphore也提供了公平與非公平鎖的機(jī)制,也可在構(gòu)造函數(shù)中進(jìn)行設(shè)定。

    Semaphore的鎖釋放操作也由手動(dòng)進(jìn)行,因此與ReentrantLock一樣,為避免線程因拋出異常而無(wú)法正常釋放鎖的情況發(fā)生,釋放鎖的操作也必須在finally代碼塊中完成

    4.AtomicInteger

    首先說(shuō)明,此處AtomicInteger是一系列相同類的代表之一,常見(jiàn)的還有AtomicLong、AtomicLong等,他們的實(shí)現(xiàn)原理相同,區(qū)別在與運(yùn)算對(duì)象類型的不同。

    我們知道,在多線程程序中,諸如++i

    i++等運(yùn)算不具有原子性,是不安全的線程操作之一。通常我們會(huì)使用synchronized將該操作變成一個(gè)原子操作,但JVM為此類操作特意提供了一些同步類,使得使用更方便,且使程序運(yùn)行效率變得更高。通過(guò)相關(guān)資料顯示,通常AtomicInteger的性能是ReentantLock的好幾倍。

    Java線程鎖總結(jié)

    1.synchronized:

    在資源競(jìng)爭(zhēng)不是很激烈的情況下,偶爾會(huì)有同步的情形下,synchronized是很合適的。原因在于,編譯程序通常會(huì)盡可能的進(jìn)行優(yōu)化synchronize,另外可讀性非常好。


    2.ReentrantLock:

    在資源競(jìng)爭(zhēng)不激烈的情形下,性能稍微比synchronized差點(diǎn)點(diǎn)。但是當(dāng)同步非常激烈的時(shí)候,synchronized的性能一下子能下降好幾十倍,而ReentrantLock確還能維持常態(tài)。

    高并發(fā)量情況下使用ReentrantLock。


    3.Atomic:

    和上面的類似,不激烈情況下,性能比synchronized略遜,而激烈的時(shí)候,也能維持常態(tài)。激烈的時(shí)候,Atomic的性能會(huì)優(yōu)于ReentrantLock一倍左右。但是其有一個(gè)缺點(diǎn),就是只能同步一個(gè)值,一段代碼中只能出現(xiàn)一個(gè)Atomic的變量,多于一個(gè)同步無(wú)效。因?yàn)樗荒茉诙鄠€(gè)Atomic之間同步。

    所以,我們寫(xiě)同步的時(shí)候,優(yōu)先考慮synchronized,如果有特殊需要,再進(jìn)一步優(yōu)化。ReentrantLock和Atomic如果用的不好,不僅不能提高性能,還可能帶來(lái)災(zāi)難。

    以上就是Java線程鎖的詳解,除了從編程的角度應(yīng)對(duì)高并發(fā),更多還需要從架構(gòu)設(shè)計(jì)的層面來(lái)應(yīng)對(duì)高并發(fā)場(chǎng)景,例如:Redis緩存、CDN、異步消息等,詳細(xì)的內(nèi)容如下。

    更多高并發(fā)架構(gòu)設(shè)計(jì)|以及最全架構(gòu)師130題|以及優(yōu)知學(xué)院最全架構(gòu)師技能高清圖

    所有以上資料獲取方式

    關(guān)注優(yōu)知學(xué)院微信公眾號(hào),回復(fù)關(guān)鍵詞 【架構(gòu)師】即可獲取以上所有架構(gòu)師資料。

    你可能也喜歡:

  • Java多線程系列(十一):ReentrantReadWriteLock的實(shí)現(xiàn)原理與鎖獲取詳解
  • Java多線程系列(七):并發(fā)容器的原理,7大并發(fā)容器詳解、及使用場(chǎng)景
  • Java多線程系列(六):深入詳解Synchronized同步鎖的底層實(shí)現(xiàn)
  • Java多線程系列(九):CountDownLatch、Semaphore等4大并發(fā)工具類詳解
  • Java多線程系列(一):最全面的Java多線程學(xué)習(xí)概述
  • Java多線程系列(十):源碼剖析AQS的實(shí)現(xiàn)原理

  • 總結(jié)

    以上是生活随笔為你收集整理的Java多线程系列(四):4种常用Java线程锁的特点,性能比较、使用场景的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。