java有哪些樂觀鎖,java的樂觀鎖

本文目錄一覽:

JAVA 悲觀鎖 樂觀鎖 區別 (認真者採納)

悲觀鎖(Pessimistic

Lock),

顧名思義,就是很悲觀,每次去拿數據的時候都認為別人會修改,所以每次在拿數據的時候都會上鎖,這樣別人想拿這個數據就會block直到它拿到鎖。傳統的關係型數據庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。

樂觀鎖(Optimistic

Lock),

顧名思義,就是很樂觀,每次去拿數據的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個數據,可以使用版本號等機制。樂觀鎖適用於多讀的應用類型,這樣可以提高吞吐量,像數據庫如果提供類似於write_condition機制的其實都是提供的樂觀鎖。

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

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

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

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

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

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

在java中有哪些鎖

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

公平鎖/非公平鎖

可重入鎖

獨享鎖/共享鎖

互斥鎖/讀寫鎖

樂觀鎖/悲觀鎖

分段鎖

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

自旋鎖

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

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中有哪些鎖,區別是什麼

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

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

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

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

ReentrantLock reentrantLock = new ReetrantLock();

1

2

【2】共享鎖和獨享鎖

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

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

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

【3】樂觀鎖和悲觀鎖。

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

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

【4】分段鎖

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

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

輕量級鎖

重量級鎖

【6】自旋鎖

自旋鎖

Java中有樂觀鎖和悲觀鎖嗎

很長就不手打了,貼一份我之前寫的答案:

樂觀鎖和悲觀鎖主要是為了解決更新丟失解決問題:

將數據庫設置為Serializable隔離級別,但是我們一般不會將數據庫設置為Serializable,那麼在非Serializable下又如何解決更新丟失?可以使用樂觀鎖、悲觀鎖。

樂觀鎖和悲觀鎖並不是數據庫中真實存在的鎖,而是兩種解決方案的名字。

(1)悲觀鎖:悲觀的認為每次操作都會更新丟失。

在查詢時,手動的加排他鎖,從而在查詢時就排除可能的更新丟失。

select * from orders where id = 8 for update;

select * from users for update;

(2)樂觀鎖:

在表中設計時添加版本字段(version),在進行修改時,要求根據具體版本進行修改,

並將版本字段+1,如果更新失敗,說明更新丟失,需要重新進行更新。

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
小藍的頭像小藍
上一篇 2024-12-23 03:47
下一篇 2024-12-23 03:48

相關推薦

  • 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
  • Python 常用數據庫有哪些?

    在Python編程中,數據庫是不可或缺的一部分。隨着互聯網應用的不斷擴大,處理海量數據已成為一種趨勢。Python有許多成熟的數據庫管理系統,接下來我們將從多個方面介紹Python…

    編程 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
  • Python通配符有哪些

    Python通配符是一種表示字符串中模糊匹配的有效工具,用於匹配與具有特定模式匹配的字符串。Python中主要的通配符有:*,?,[]和{}。 一、星號通配符 * 在Python中…

    編程 2025-04-29

發表回復

登錄後才能評論