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

synchronized?和?Lock?的異同點(diǎn)(如何讓選擇)

 更新時(shí)間:2022年09月08日 09:36:44   作者:會(huì)飛的湯姆貓???????  
這篇文章主要介紹了?synchronized和Lock的異同點(diǎn)(如何讓選擇),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下

前言:

我們主要學(xué)習(xí) synchronized 和 Lock 的異同點(diǎn),以及該如何選擇。

相同點(diǎn)

synchronized 和 Lock 的相同點(diǎn)非常多,我們這里重點(diǎn)講解 3 個(gè)比較大的相同點(diǎn)。

  • synchronized 和 Lock 都是用來保護(hù)資源線程安全的。

這一點(diǎn)毋庸置疑,這是它們的基本作用。

  • 都可以保證可見性。

對(duì)于 synchronized 而言,線程 A 在進(jìn)入 synchronized 塊之前或在 synchronized 塊內(nèi)進(jìn)行操作,對(duì)于后續(xù)的獲得同一個(gè) monitor 鎖的線程 B 是可見的,也就是線程 B 是可以看到線程 A 之前的操作的,這也體現(xiàn)了 happens-before 針對(duì) synchronized 的一個(gè)原則。

而對(duì)于 Lock 而言,它和 synchronized 是一樣,都可以保證可見性,如圖所示,在解鎖之前的所有操作對(duì)加鎖之后的所有操作都是可見的。

如果你之前不了解什么是可見性,此時(shí)理解可能會(huì)有一定的困難,可以在學(xué)習(xí)本專欄的 Java 內(nèi)存模型相關(guān)內(nèi)容后,再復(fù)習(xí)本課時(shí),就會(huì)豁然開朗。

  • synchronized 和 ReentrantLock 都擁有可重入的特點(diǎn)。

這里的 ReentrantLock 是 Lock 接口的一個(gè)最主要的實(shí)現(xiàn)類,在對(duì)比 synchronized 和 Lock 的時(shí)候,也會(huì)選擇 Lock 的主要實(shí)現(xiàn)類來進(jìn)行對(duì)比。可重入指的是某個(gè)線程如果已經(jīng)獲得了一個(gè)鎖,現(xiàn)在試圖再次請(qǐng)求這個(gè)它已經(jīng)獲得的鎖,如果它無需提前釋放這個(gè)鎖,而是直接可以繼續(xù)使用持有的這個(gè)鎖,那么就是可重入的。如果必須釋放鎖后才能再次申請(qǐng)這個(gè)鎖,就是不可重入的。而 synchronized 和 ReentrantLock 都具有可重入的特性。

不同點(diǎn)

下面我們來看下 synchronized 和 Lock 的區(qū)別,和相同點(diǎn)一樣,它們之間也有非常多的區(qū)別,這里講解其中比較大的 7 點(diǎn)不同。

用法區(qū)別:

synchronized 關(guān)鍵字可以加在方法上,不需要指定鎖對(duì)象(此時(shí)的鎖對(duì)象為 this),也可以新建一個(gè)同步代碼塊并且自定義 monitor 鎖對(duì)象;而 Lock 接口必須顯示用 Lock 鎖對(duì)象開始加鎖 lock() 和解鎖 unlock(),并且一般會(huì)在 finally 塊中確保用 unlock() 來解鎖,以防發(fā)生死鎖。

與 Lock 顯式的加鎖和解鎖不同的是 synchronized 的加解鎖是隱式的,尤其是拋異常的時(shí)候也能保證釋放鎖,但是 Java 代碼中并沒有相關(guān)的體現(xiàn)。

加解鎖順序不同:

對(duì)于 Lock 而言如果有多把 Lock 鎖,Lock 可以不完全按照加鎖的反序解鎖,比如我們可以先獲取 Lock1 鎖,再獲取 Lock2 鎖,解鎖時(shí)則先解鎖 Lock1,再解鎖 Lock2,加解鎖有一定的靈活度,如代碼所示。

lock1.lock();
lock2.lock();
...
lock1.unlock();
lock2.unlock();

但是 synchronized 無法做到,synchronized 解鎖的順序和加鎖的順序必須完全相反,例如:

synchronized(obj1){
    synchronized(obj2){
        ...
    }
}

那么在這里,順序就是先對(duì) obj1 加鎖,然后對(duì) obj2 加鎖,然后對(duì) obj2 解鎖,最后解鎖 obj1。這是因?yàn)?synchronized 加解鎖是由 JVM 實(shí)現(xiàn)的,在執(zhí)行完 synchronized 塊后會(huì)自動(dòng)解鎖,所以會(huì)按照 synchronized 的嵌套順序加解鎖,不能自行控制。

synchronized 鎖不夠靈活

一旦 synchronized 鎖已經(jīng)被某個(gè)線程獲得了,此時(shí)其他線程如果還想獲得,那它只能被阻塞,直到持有鎖的線程運(yùn)行完畢或者發(fā)生異常從而釋放這個(gè)鎖。如果持有鎖的線程持有很長時(shí)間才釋放,那么整個(gè)程序的運(yùn)行效率就會(huì)降低,而且如果持有鎖的線程永遠(yuǎn)不釋放鎖,那么嘗試獲取鎖的線程只能永遠(yuǎn)等下去。

相比之下,Lock 類在等鎖的過程中,如果使用的是 lockInterruptibly 方法,那么如果覺得等待的時(shí)間太長了不想再繼續(xù)等待,可以中斷退出,也可以用 tryLock() 等方法嘗試獲取鎖,如果獲取不到鎖也可以做別的事,更加靈活。

  • synchronized 鎖只能同時(shí)被一個(gè)線程擁有,但是 Lock 鎖沒有這個(gè)限制

例如在讀寫鎖中的讀鎖,是可以同時(shí)被多個(gè)線程持有的,可是 synchronized 做不到。

  • 原理區(qū)別 synchronized 是內(nèi)置鎖,由 JVM 實(shí)現(xiàn)獲取鎖和釋放鎖的原理,還分為偏向鎖、輕量級(jí)鎖、重量級(jí)鎖。

Lock 根據(jù)實(shí)現(xiàn)不同,有不同的原理,例如 ReentrantLock 內(nèi)部是通過 AQS 來獲取和釋放鎖的。

是否可以設(shè)置公平/非公平:

公平鎖是指多個(gè)線程在等待同一個(gè)鎖時(shí),根據(jù)先來后到的原則依次獲得鎖。ReentrantLock 等 Lock 實(shí)現(xiàn)類可以根據(jù)自己的需要來設(shè)置公平或非公平,synchronized 則不能設(shè)置。

性能區(qū)別:

在 Java 5 以及之前,synchronized 的性能比較低,但是到了 Java 6 以后,發(fā)生了變化,因?yàn)?JDK 對(duì) synchronized 進(jìn)行了很多優(yōu)化,比如自適應(yīng)自旋、鎖消除、鎖粗化、輕量級(jí)鎖、偏向鎖等,所以后期的 Java 版本里的 synchronized 的性能并不比 Lock 差。

如何選擇

講完了 synchronized 和 Lock 的相同點(diǎn)和區(qū)別,最后我們?cè)賮砜聪氯绾芜x擇它們,

在 Java 并發(fā)編程實(shí)戰(zhàn)和 Java 核心技術(shù)里都認(rèn)為:

  • 如果能不用最好既不使用 Lock 也不使用 synchronized。因?yàn)樵谠S多情況下你可以使用 java.util.concurrent 包中的機(jī)制,它會(huì)為你處理所有的加鎖和解鎖操作,也就是推薦優(yōu)先使用工具類來加解鎖。
  • 如果 synchronized 關(guān)鍵字適合你的程序, 那么請(qǐng)盡量使用它,這樣可以減少編寫代碼的數(shù)量,減少出錯(cuò)的概率。因?yàn)橐坏┩浽?finally 里 unlock,代碼可能會(huì)出很大的問題,而使用 synchronized 更安全。
  • 如果特別需要 Lock 的特殊功能,比如嘗試獲取鎖、可中斷、超時(shí)功能等,才使用 Lock。

到此這篇關(guān)于 synchronized 和 Lock 的異同點(diǎn)(如何讓選擇)的文章就介紹到這了,更多相關(guān) synchronized 和 Lock 區(qū)別內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)TopK問題的方法

    Java實(shí)現(xiàn)TopK問題的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)TopK問題的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • java 虛擬機(jī)中對(duì)象訪問詳解

    java 虛擬機(jī)中對(duì)象訪問詳解

    這篇文章主要介紹了java 虛擬機(jī)中對(duì)象訪問詳解的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • java基礎(chǔ)之TreeMap實(shí)現(xiàn)類全面詳解

    java基礎(chǔ)之TreeMap實(shí)現(xiàn)類全面詳解

    這篇文章主要為大家介紹了java基礎(chǔ)之TreeMap實(shí)現(xiàn)類全面詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Java實(shí)現(xiàn)雙端鏈表LinkedList

    Java實(shí)現(xiàn)雙端鏈表LinkedList

    本文主要介紹了Java實(shí)現(xiàn)雙端鏈表LinkedList,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • java多線程事務(wù)加鎖引發(fā)bug用戶重復(fù)注冊(cè)解決分析

    java多線程事務(wù)加鎖引發(fā)bug用戶重復(fù)注冊(cè)解決分析

    這篇文章主要為大家介紹了java多線程事務(wù)加鎖引發(fā)bug用戶重復(fù)注冊(cè)解決分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Spring注解開發(fā)@Bean和@ComponentScan使用案例

    Spring注解開發(fā)@Bean和@ComponentScan使用案例

    這篇文章主要介紹了Spring注解開發(fā)@Bean和@ComponentScan使用案例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • SpringBoot中默認(rèn)緩存實(shí)現(xiàn)方案的示例代碼

    SpringBoot中默認(rèn)緩存實(shí)現(xiàn)方案的示例代碼

    這篇文章主要介紹了SpringBoot中默認(rèn)緩存實(shí)現(xiàn)方案,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 詳解Java文件下載的幾種實(shí)現(xiàn)方式

    詳解Java文件下載的幾種實(shí)現(xiàn)方式

    這篇文章主要介紹了詳解Java文件下載的幾種實(shí)現(xiàn)方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • 初識(shí)sa-token及登錄授權(quán)簡單實(shí)現(xiàn)

    初識(shí)sa-token及登錄授權(quán)簡單實(shí)現(xiàn)

    這篇文章主要為大家介紹了sa-token及登錄授權(quán)簡單實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-07-07
  • spring boot項(xiàng)目中MongoDB的使用方法

    spring boot項(xiàng)目中MongoDB的使用方法

    前段時(shí)間分享了關(guān)于Spring Boot中使用Redis的文章,除了Redis之后,我們?cè)诨ヂ?lián)網(wǎng)產(chǎn)品中還經(jīng)常會(huì)用到另外一款著名的NoSQL數(shù)據(jù)庫MongoDB。下面這篇文章主要給大家介紹了關(guān)于在spring boot項(xiàng)目中MongoDB的使用方法,需要的朋友可以參考下。
    2017-09-09

最新評(píng)論

会泽县| 于都县| 什邡市| 泰顺县| 军事| 临夏市| 荣成市| 宝丰县| 万载县| 沂源县| 施甸县| 万荣县| 阿合奇县| 方正县| 宁强县| 武汉市| 湘西| 永嘉县| 五常市| 揭东县| 拉孜县| 内丘县| 潜山县| 和平县| 西平县| 崇义县| 金华市| 东乌珠穆沁旗| 玉环县| 天等县| 云安县| 外汇| 宜章县| 汝州市| 瑞丽市| 当阳市| 博客| 安达市| 大宁县| 通道| 嘉荫县|