Java之多線程里面的鎖理解以及synchronized與Lock的區別

一、宏觀的說下鎖的分類

1)鎖分為樂觀鎖、悲觀鎖

悲觀鎖認為對于同一個數據的并發操作,一定是會發生修改的,哪怕沒有修改,也會認為修改。因此對于同一個數據的并發操作,悲觀鎖采取加鎖的形式。悲觀的認為,不加鎖的并發操作一定會出問題。
樂觀鎖則認為對于同一個數據的并發操作,是不會發生修改的。在更新數據的時候,會采用嘗試更新,不斷重新的方式更新數據。樂觀的認為,不加鎖的并發操作是沒有事情的


2)鎖分為公平鎖、非公平鎖
公平鎖是指多個線程按照申請鎖的順序來獲取鎖。
非公平鎖是指多個線程獲取鎖的順序并不是按照申請鎖的順序,有可能后申請的線程比先申請的線程優先獲取鎖。有可能,會造成優先級反轉或者饑餓現象。

?

3)鎖分為獨享鎖、共享鎖
獨享鎖是指該鎖一次只能被一個線程所持有。
共享鎖是指該鎖可被多個線程所持有。

?

?

?

?

二、java中常見具體高并發鎖

1)synchronized
synchronized機制是給共享資源上鎖,只有拿到鎖的線程才可以訪問共享資源,這樣就可以強制使得對共享資源的訪問都是順序的,夠保證在同一個時刻最多只有一個線程執行同一個對象的同步代碼,可保證修飾的代碼在執行過程中不會被其他線程干擾

synchronized(obj) {}

synchronized實現的機理依賴于軟件層面上的JVM,對于Synchronized而言,也是一種悲觀鎖、非公平鎖、也是獨享鎖、也是互斥鎖。

?

?

2)ReentrantLock
可重入鎖,顧名思義,這個鎖可以被線程多次重復進入進行獲取操作
Lock實現的機理依賴于特殊的CPU指令比如執行lock()方法的時候,cpu發出lock指令,比如我們執行unlock的時候,cpu發出lock指令可以認為不受JVM的約束,并可以通過其他語言平臺來完成底層的實現。在并發量較小的多線程應用程序中,ReentrantLock與synchronized性能相差無幾,但在高并發量的條件下,synchronized性能會迅速下降幾十倍,而ReentrantLock的性能卻能依然維持一個水準,高并發量情況下使用ReentrantLock。

ReentrantLock通過方法lock()與unlock()來進行加鎖與解鎖操作,與synchronized會被JVM自動解鎖機制不同,ReentrantLock加鎖后需要手動進行解鎖。為了避免程序出現異常而無法正常解鎖的情況,使用ReentrantLock必須在finally控制塊中進行解鎖操作。通常使用方式如下所示

Lock lock = new ReentrantLock();try {lock.lock();}finally {lock.unlock();}

對于ReentrantLock而言,ReentrantLock在構造函數中提供了是否公平鎖的初始化方式,默認為非公平鎖。這是因為,非公平鎖實際執行的效率要遠遠超出公平鎖、ReentrantLock也是互斥鎖、也是獨享鎖。

?

?

3)Semaphore
互斥是進程同步關系的一種特殊情況,相當于只存在一個臨界資源,因此同時最多只能給一個線程提供服務。但是,在實際復雜的多線程應用程序中,可能存在多個臨界資源,這時候我們可以借助Semaphore信號量來完成多個臨界資源的訪問
,通過acquire()與release()方法來獲得和釋放臨界資源,Semaphore和ReentrantLock用法差不多,Semaphore的鎖釋放操作也由手動進行,因此與ReentrantLock一樣,為避免線程因拋出異常而無法正常釋放鎖的情況發生,釋放鎖的操作也必須在finally代碼塊中完成,
構造方法里面也可以設置否公平鎖的初始化方式,默認為非公平鎖

?

?

4)AtomicInteger
在多線程程序中,諸如++i或i++等運算不具有原子性,是不安全的線程操作之一。通常我們會使用synchronized將該操作變成一個原子操作,但JVM為此類操作特意提供了一些同步類,使得使用更方便,且使程序運行效率變得更高。通常AtomicInteger的性能是ReentantLock的好幾倍。

?

?

?

?

三、各個鎖的優勢

1.synchronized:

在資源競爭不是很激烈的情況,偶爾會有同步的情形下,synchronized是很合適的。原因在于,編譯程序通常會盡可能的進行優化synchronize,另外可讀性非常好,synchronized它是通過悲觀鎖實現的。

?

2.ReentrantLock:

在資源競爭不激烈的情形下,性能稍微比synchronized差點點。但是當同步非常激烈的時候,synchronized的性能一下子能下降好幾十倍,而ReentrantLock確還能維持常態。

高并發量情況下使用ReentrantLock。

?

3.Atomic:

和上面的類似,不激烈情況下,性能比synchronized略遜,而激烈的時候,也能維持常態。激烈的時候,Atomic的性能會優于ReentrantLock一倍左右。但是其有一個缺點,就是只能同步一個值,一段代碼中只能出現一個Atomic的變量,多于一個同步無效。因為他不能在多個Atomic之間同步,是基于cas操作來實現的,它是通過樂觀鎖來實現的。
?

參考地址:https://youzhixueyuan.com/4-kinds-of-java-thread-locks.html? 然后自己再對比比較和精簡分析

?

?

4?synchronized與Lock的區別

1).首先synchronized是java內置關鍵字,是在在jvm層面Lock是一個接口,最后是由CPU來發送lock和unlock指令,這個和volatile底層原理實現類似。

2).synchronized無法判斷是否獲取鎖的狀態,Lock可以判斷是否獲取到鎖

3 ) .synchronized會自動釋放鎖(a?線程執行完同步代碼會釋放鎖 ;b 線程執行過程中發生異常會釋放鎖),Lock需在finally中手工釋放鎖(unlock()方法釋放鎖),否則容易造成線程死鎖;

4) .用synchronized關鍵字的兩個線程1和線程2,如果當前線程1獲得鎖,線程2線程等待。如果線程1阻塞,線程2則會一直等待下去,而Lock鎖就不一定會等待下去,如果嘗試獲取不到鎖,線程可以不用一直等待就結束了;

5) .synchronized的鎖可重入、不可中斷、非公平,而Lock鎖可重入、可判斷、可公平(兩者皆可)

6) .Lock鎖適合大量同步的代碼的同步問題,synchronized鎖適合代碼少量的同步問題。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/287887.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/287887.shtml
英文地址,請注明出處:http://en.pswp.cn/news/287887.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實驗報告類與對象水井問題_物業設施設備巡檢檢查對象、周期和頻次

點擊上方“物業精英俱樂部”,關注公眾號,中國物業管理行業精英聯盟,中國百強物業企業精英學習平臺。來源:百度文庫版權歸原創作者所有一巡檢對象、周期和頻次所謂巡檢,并不是說將大大小小的所有物業設施都列入巡檢范圍&#xff0c…

龍芯2K1000LA處理器流片成功,龍芯業務全面轉向LoongArch架構

2022年4月底,龍芯2K1000處理器完成了改版芯片(代號龍芯2K1000LA)的功能和性能測試,正在開展用戶試用。龍芯2K1000LA在實現與原有版本2K1000引腳和接口兼容的基礎上,處理器核更新為基于龍芯自主指令系統架構LoongArch&a…

php基礎教程 第十一步 面向對象補充

繼承 上一節中學習了php類,以及類方法、類成員變量相關的一些知識,接下來開始學習php類中的繼承。本節是上一節的補充。(其實也就是為了保持日更隨便發的一篇文) 開始 php繼承是繼承與父類的所有屬性,就像你繼承了你…

ArcGIS實驗教程——實驗十五:拓撲關系創建與編輯

ArcGIS實驗視頻教程合集:《ArcGIS實驗教程從入門到精通》(附配套實驗數據) 一、實驗描述 1、拓撲關系的概念 拓撲關系是指滿足拓撲幾何學原理的各空間數據間的相互關系。即用結點、弧段和多邊形所表示的實體之間的鄰接、關聯、包含和連通關系。如:點與點的鄰接關系、點與面…

Sql Server 優化 SQL 查詢:如何寫出高性能SQL語句

1、 首先要搞明白什么叫執行計劃? 執行計劃是數據庫根據SQL語句和相關表的統計信息作出的一個查詢方案,這個方案是由查詢優化器自動分析產生的,比如一條SQL語句如果用來從一個 10萬條記錄的表中查1條記錄,那查詢優化器會選擇“索引…

【Ubuntu】ubuntu物理機安裝方法:wubi

在之前的文章里我們曾經詳細介紹了如何在虛擬機里安裝ubuntu操作系統,但是一些小伙伴希望在自己的電腦里安裝一個ubuntu,來感受一下ubuntu的硬體驗。下面給大家介紹一種通過wubi的安裝方法。 wubi是 Windows Ubuntu-Based Installer 縮寫,是一…

Java之ThreadLocal

1 ThreadLocal接口出現原因 使用ThreadLocal保存當前線程的變量值,這樣你想獲取該變量的值的時候,獲取到的都是本線程的變量值,不會獲取到其他線程設置的值,早在JDK 1.2的版本中就提供java.lang.ThreadLocal,ThreadLo…

server如何調用 thrift_Thrift總結(二)如何快速創建自己的RPC服務

前面介紹了thrift 基礎的東西,怎么寫thrift 語法規范編寫腳本,如何生成相關的語言的接口。不清楚的可以看這個《Thrift總結(一)介紹》。做好之前的準備工作以后,下面就開始如何用Thrift寫RPC接口。如何用Thrift寫RPC接口1. 打開之前下載的thr…

Hello Playwright:(2)簡化部署方式

前言上次的文章Hello Playwright:(1)從開發到部署發表后,有網友留言問,有不有簡化部署的方式:下面,提供 2 種可行的方案。方案 1. Copy其實 Playwright 默認是到C:\Users\用戶名\AppData\Local\ms-playwright文件夾下查…

ArcGIS實驗教程——實驗十六:空間數據查詢

ArcGIS實驗視頻教程合集:《ArcGIS實驗教程從入門到精通》(附配套實驗數據) 一、實驗描述 空間數據庫查詢定義:從空間數據庫中找出所有滿足屬性約束條件和空間約束條件的地理對象。 二、實驗內容 (一)屬性查詢 1、簡單查詢 2、SQL查詢 (二)圖形查詢 1、點查詢 2…

C++入門指南及實戰 第一步 概述及經典HelloWorld

本系列文章環境及學習門檻 編程基礎:無年齡:具有一定的邏輯思維英文:不要求數學:不要求學習時長:每天一篇,一周4-5篇即可,每篇最多1小時死記硬背:不需要,理解至上本機環…

【數學題】男女的比例

在一個重男輕女的國家里,每家每戶都想生男孩。若一戶人家生了一個男孩,就不會再生了。若一家生了一個女孩,便會再生一個,直到生下男孩為止。請問這個國家(有無限多的人民)的男女比例是多少?答案:1比1。在某一戶人家中…

為什么云服務器沒西南的_去年“雙11“我買的那臺云服務器

一、為什么會買云服務器為什么初學者需要一臺云服務器?從我自己那僅有的一點經驗來看,重點無非這一個詞:實踐。細數一下初學者擁有一臺云服務器的好處:學習操作系統、熟悉環境大部分初學者在本地使用的是windows系統,在…

Java線程安全以及線程安全的實現方式和內存模型(JMM)

一、了解幾個概念 1)臨界區: 臨界區指的是一個訪問共用資源(例如:共用設備或是共用存儲器)的程序片段,而這些共用資源又無法同時被多個線程訪問的特性。當有線程進入臨界區段時,其他線程或是進…

animate 實現滑動切換效果

今天和大家分享一下用 animate 實現滑動切換效果的小例子 ------- 來自<一只有夢想的前端小白> 大家都知道jQuery 提供的有一下幾種方法能夠實現滑動效果&#xff1a; slideDown()slideUp()slideToggle()但是以上的滑動不太方便控制其滑動的方向&#xff0c;所以我們還是…

[不一樣的依賴注入]通過遞歸實現容器里依賴注入

遞歸實現依賴注入創建所需的依賴服務類1public class Test2{3 public void PrintTest()4 {5 Console.WriteLine("Hello World");6 }7}89public class Test2 10{ 11 private readonly Test _test; 12 13 public Test2(Test test) 14 { 15 …

ArcGIS實驗教程——實驗十七:緩沖區分析(Buffer Analysis)

ArcGIS實驗視頻教程合集:《ArcGIS實驗教程從入門到精通》(附配套實驗數據) 【實驗描述】 緩沖區(Buffer)是為了識別某一地理實體對周圍地物的影響而在其周圍建立的一定寬度多邊形區域,緩沖區分析(Buffer Analysis)是用來確定不同地理要素的空間臨近性或接近程度的一種分…

Java之jdk和CGLib實現動態代理

1 jdk實現動態代理源碼實現 這里需要用到InvocationHandler接口 public interface Hello {public void sayHello(); } public class HelloImpl implements Hello {Overridepublic void sayHello() {System.out.println("hello word");} }import java.lang.reflect…

從Visual Studio中生成Linux設備

本文講的是從Visual Studio中生成Linux設備&#xff0c;【IT168 云計算頻道】近日Novell發布了SUSE Studio&#xff1a;一個用于創建Linux設備&#xff08;appliance&#xff09;的工具。與此同時&#xff0c;Mono小組創建了一個插件以從Visual Studio中生成支持SUSE的設備。 …

C++入門指南及實戰 第二步 HelloWorld及擴展詳解

回顧 在上一節中&#xff0c;我們編寫了如下代碼&#xff0c;完成了 HelloWorld程序的編寫&#xff1a; #include<iostream> using namespace std;int main(){cout <<"Hello World";return 0; }本小節將會對該代碼進行講解&#xff0c;并且解釋一下專業…