java中的鎖,java中的鎖機制

本文目錄一覽:

JAVA多線程中“鎖”的概念的理解

當有多個線程共用一種臨界資源的時候,便會出現衝突,鎖就是用來解決這種衝突的,跟上廁所一樣,假如有ABC三個人都來上廁所而廁所只有一個一次只能進一人,A先來了,那麼在A出來之前,這個廁所就處在了“鎖”定狀態,B和C憋死也要在外面等着,直到A出門(原因很多,如睡著了,方便完了,忘帶廁紙了跑出來找人要….)“鎖”定解除B和C才能進入,當然牛逼的進(A和B有一腿只讓B進或者優先級高或者…),SB的在外面繼續等。此乃吾理解之鎖定,希望能夠對你有所幫助

Java中有哪些鎖,區別是什麼

【1】公平所和非公平所。

公平鎖:是指按照申請鎖的順序來獲取鎖,

非公平所:線程獲取鎖的順序不一定按照申請鎖的順序來的。

//默認是不公平鎖,傳入true為公平鎖,否則為非公平鎖

ReentrantLock reentrantLock = new ReetrantLock();

1

2

【2】共享鎖和獨享鎖

獨享鎖:一次只能被一個線程所訪問

共享鎖:線程可以被多個線程所持有。

ReadWriteLock 讀鎖是共享鎖,寫鎖是獨享鎖。

【3】樂觀鎖和悲觀鎖。

樂觀鎖:對於一個數據的操作並發,是不會發生修改的。在更新數據的時候,會嘗試採用更新,不斷重入的方式,更新數據。

悲觀鎖:對於同一個數據的並發操作,是一定會發生修改的。因此對於同一個數據的並發操作,悲觀鎖採用加鎖的形式。悲觀鎖認為,不加鎖的操作一定會出問題,

【4】分段鎖

1.7及之前的concurrenthashmap。並發操作就是分段鎖,其思想就是讓鎖的粒度變小。

【5】偏向鎖是指一段同步代碼一直被一個線程所訪問,那麼該線程會自動獲取鎖。降低獲取鎖的代價

輕量級鎖

重量級鎖

【6】自旋鎖

自旋鎖

在java中有哪些鎖

給你整理了Java中的一些鎖:

公平鎖/非公平鎖

可重入鎖

獨享鎖/共享鎖

互斥鎖/讀寫鎖

樂觀鎖/悲觀鎖

分段鎖

偏向鎖/輕量級鎖/重量級鎖

自旋鎖

上面是很多鎖的名詞,這些分類並不是全是指鎖的狀態,有的指鎖的特性,有的指鎖的設計

java中悲觀鎖和樂觀鎖的區別

樂觀鎖和悲觀鎖的區別如下:

1、悲觀鎖是當線程拿到資源時,就對資源上鎖,並在提交後,才釋放鎖資源,其他線程才能使用資源。

2、樂觀鎖是當線程拿到資源時,上樂觀鎖,在提交之前,其他的鎖也可以操作這個資源,當有衝突的時候,並發機制會保留前一個提交,打回後一個提交,讓後一個線程重新獲取資源後,再操作,然後提交。和git上傳代碼一樣,兩個線程都不是直接獲取資源本身,而是先獲取資源的兩個copy版本,然後在這兩個copy版本上修改。

3、悲觀鎖和樂觀鎖在並發量低的時候,性能差不多,但是在並發量高的時候,樂觀鎖的性能遠遠優於悲觀鎖。

4、常用的synchronized是悲觀鎖,lock是樂觀鎖。

java 鎖有幾種

樂觀鎖/悲觀鎖

樂觀鎖與悲觀鎖不是指具體的什麼類型的鎖,而是指看待並發同步的角度。

悲觀鎖認為對於同一個數據的並發操作,一定是會發生修改的,哪怕沒有修改,也會認為修改。因此對於同一個數據的並發操作,悲觀鎖採取加鎖的形式。悲觀的認為,不加鎖的並發操作一定會出問題。

樂觀鎖則認為對於同一個數據的並發操作,是不會發生修改的。在更新數據的時候,會採用嘗試更新,不斷重新的方式更新數據。樂觀的認為,不加鎖的並發操作是沒有事情的。

從上面的描述我們可以看出,悲觀鎖適合寫操作非常多的場景,樂觀鎖適合讀操作非常多的場景,不加鎖會帶來大量的性能提升。

公平鎖/非公平鎖

公平鎖是指多個線程按照申請鎖的順序來獲取鎖。

非公平鎖是指多個線程獲取鎖的順序並不是按照申請鎖的順序,有可能後申請的線程比先申請的線程優先獲取鎖。

優點:在於吞吐量比公平鎖大。

缺點:可能會造成優先級反轉或者某些線程飢餓現象(一直拿不到鎖)。

對於Java ReentrantLock而言,通過構造函數指定該鎖是否是公平鎖,默認是非公平鎖。

對於Synchronized而言,也是一種非公平鎖。由於其並不像ReentrantLock是通過AQS的來實現線程調度,所以並沒有任何辦法使其變成公平鎖。

可重入鎖

可重入鎖的概念是自己可以再次獲取自己的內部鎖。

舉個例子,比如一條線程獲得了某個對象的鎖,此時這個對象鎖還沒有釋放,當其再次想要獲取這個對象的鎖的時候還是可以獲取的(如果不可重入的鎖的話,此刻會造成死鎖)。說的更高深一點可重入鎖是一種遞歸無阻塞的同步機制。

對於Java ReentrantLock而言, 他的名字就可以看出是一個可重入鎖,其名字是Re entrant Lock重新進入鎖。

對於Synchronized而言,也是一個可重入鎖。可重入鎖的一個好處是可一定程度避免死鎖。

獨享鎖/共享鎖

獨享鎖是指該鎖一次只能被一個線程所持有。

共享鎖是指該鎖可被多個線程所持有。

對於Java ReentrantLock(互斥鎖)而言,其是獨享鎖。

但是對於Lock的另一個實現類ReadWriteLock(讀寫鎖),其讀鎖是共享鎖,其寫鎖是獨享鎖。讀鎖的共享鎖可保證並發讀是非常高效的,讀寫,寫讀 ,寫寫的過程是互斥的。

對於Synchronized而言,當然是獨享鎖。

分段鎖

分段鎖其實是一種鎖的設計,並不是具體的一種鎖。對於ConcurrentHashMap而言,其並發的實現就是通過分段鎖的形式來實現高效的並發操作。

我們以ConcurrentHashMap來說一下分段鎖的含義以及設計思想,ConcurrentHashMap中的分段鎖稱為Segment,它即類似於HashMap(JDK7與JDK8中HashMap的實現)的結構,即內部擁有一個Entry數組,數組中的每個元素又是一個鏈表;同時又是一個ReentrantLock(Segment繼承了ReentrantLock)。

當需要put元素的時候,並不是對整個hashmap進行加鎖,而是先通過hashcode來知道他要放在那一個分段中,然後對這個分段進行加鎖,所以當多線程put的時候,只要不是放在一個分段中,就實現了真正的並行的插入。

但是,在統計size的時候,可就是獲取hashmap全局信息的時候,就需要獲取所有的分段鎖才能統計。

分段鎖的設計目的是細化鎖的粒度,當操作不需要更新整個數組的時候,就僅僅針對數組中的一項進行加鎖操作。

互斥鎖:

無法獲取瑣時,進線程立刻放棄剩餘的時間片並進入阻塞(或者說掛起)狀態,同時保存寄存器和程序計數器的內容(保存現場,上下文切換的前半部分),當可以獲取鎖時,進線程激活,等待被調度進CPU並恢復現場(上下文切換下半部分)

上下文切換會帶來數十微秒的開銷,不要在性能敏感的地方用互斥鎖

讀寫鎖:

1)多個讀者可以同時進行讀

2)寫者必須互斥(只允許一個寫者寫,也不能讀者寫者同時進行)

3)寫者優先於讀者(一旦有寫者,則後續讀者必須等待,喚醒時優先考慮寫者)

自旋鎖:

自旋鎖是指嘗試獲取鎖的線程不會立即阻塞,而是採用循環的方式去嘗試獲取鎖,這樣的好處是減少線程上下文切換的消耗,缺點是循環會消耗CPU。

java中的鎖有哪幾種

lock比synchronized比較如下:

1) 支持公平鎖,某些場景下需要獲得鎖的時間與申請鎖的時間相一致,但是synchronized做不到

2) 支持中斷處理,就是說那些持有鎖的線程一直不釋放,正在等待的線程可以放棄等待。如果不支持中斷處理,那麼線程可能一直無限制的等待下去,就算那些正在佔用資源的線程死鎖了,正在等待的那些資源還是會繼續等待,但是ReentrantLock可以選擇放棄等待

3) condition和lock配合使用,以獲得最大的性能

JAVA中鎖使用的幾點建議:

1.如果沒有特殊的需求,建議使用synchronized,因為操作簡單,便捷,不需要額外進行鎖的釋放。鑒於JDK1.8中的ConcurrentHashMap也使用了CAS+synchronized的方式替換了老版本中使用分段鎖(ReentrantLock)的方式,可以得知,JVM中對synchronized的性能做了比較好的優化。

2.如果代碼中有特殊的需求,建議使用Lock。例如並發量比較高,且有些操作比較耗時,則可以使用支持中斷的所獲取方式;如果對於鎖的獲取,講究先來後到的順序則可以使用公平鎖;另外對於多個變量的鎖保護可以通過lock中提供的condition對象來和lock配合使用,獲取最大的性能。

原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/190918.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-11-30 09:07
下一篇 2024-11-30 09:07

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論