Synchronized方法鎖、對象鎖、類鎖區別

synchronized,這個東西我們一般稱之為”同步鎖“,他在修飾代碼塊的時候需要傳入一個引用對象作為“鎖”的對象。

  1. 在修飾方法的時候,默認是當前對象作為鎖的對象
  2. 在修飾類時,默認是當前類的Class對象作為所的對象
    故存在著方法鎖、對象鎖、類鎖 這樣的概念
    那么我們來大致看一下這三種鎖

一、方法鎖(synchronized修飾方法時)(其實也可以算是對象鎖)

通過在方法聲明中加入synchronized關鍵字來聲明synchronized方法。
synchronized 方法鎖控制對類成員變量的訪問:
每個類實例對應一把鎖
每個synchronized方法都必須獲得調用該方法的類實例的”鎖“方能執行,否則所屬線程阻塞。

方法一旦執行,就會獨占該鎖,一直到從該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得該鎖,從而重新進入可執行狀態。

這種機制確保了同一時刻對于每一個類的實例,其所有聲明為synchronized的成員函數中之多只有一個處于可執行狀態,從而有效避免了類成員變量的訪問沖突。

ok,下方介紹一個火車站賣票的例子,一共1000張票,有4個窗口賣票,賣票的方法被我定義為同步的,即每個賣票過程會賣出4張票,賣完之后才允許其他窗口賣票

大家看看代碼,體會一下

public class LockTest {static int tickets = 1000;public synchronized void sellTickets(){int i=4;while (i>0){i--;tickets--;System.out.println(Thread.currentThread().getName()+":"+tickets);}}public static void main(String[] args) {LockTest lockTest = new LockTest();Thread thread1 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread2 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread3 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});Thread thread4 = new Thread(new Runnable() {@Overridepublic void run() {lockTest.sellTickets();}});thread1.start();thread2.start();thread3.start();thread4.start();}
}

運行結果如下:

運行結果多運行幾次會發現雖然線程的先后順序會變化,但是每一個線程必定先賣出4張票之后才會去接著賣剩余的票。

下邊我們來看下對象鎖,其實方法鎖 這個就屬于對象鎖

二、對象鎖(synchronized修飾方法或代碼塊)

當一個對象中有synchronized method 或synchronized block 的時候,調用此對象的同步方法或進入其同步區域時,就必須先獲得對象鎖。

如果此對象的對象鎖已被其他調用者占用,則需要等待此鎖被釋放。(方法鎖也是對象鎖)

java的所有對象都含有一個互斥鎖,這個鎖由jvm自動獲取和釋放。

線程進入synchronized 方法的時候獲取該對象的鎖,當然如果已經有線程獲取了這個對象的鎖,那么當前線程會等待;

synchronized方法正常返回或者拋異常而終止,jvm會自動釋放對象鎖。這里也體現了用synchronized來加鎖的一個好處,即 :

方法拋異常的時候,鎖仍然可以由jvm來自動釋放
對象鎖的兩種方式

1、方法鎖,上面已提及。

2、代碼塊形式

public void sellTickets(){int i=4;synchronized(this) {while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}}

執行效果一樣。

三、類鎖(synchronized修飾靜態的方法或者代碼塊)

由于一個class不論被實例化多少次,其中的靜態方法和靜態變量在內存中都只有一份。所以,一旦一個靜態的方法被聲明為synchronized。此類所有的實例對象在調用此方法,共用同一把鎖,我們稱之為類鎖。
對象鎖是用來控制實例方法之間的同步,而類鎖是用來控制靜態方法(或者靜態變量互斥體)之間的同步的。
類鎖只是一個概念上的東西,并不是真實存在的,他只是用來幫助我們理解鎖定實例方法和靜態方法的區別的。
java類可能會有很多對象,但是只有一個Class(字節碼)對象,也就是說類的不同實例之間共享該類的Class對象。Class對象其實也僅僅是1個java對象,只不過有點特殊而已。
由于每個java對象都有1個互斥鎖,而類的靜態方法是需要Class對象。所以所謂的類鎖,只不過是Class對象的鎖而已。
獲取類的Class對象的方法有好幾種,最簡單的是[類名.class]的方式。(百度:獲取字節碼的三種方式)

來看下類鎖的兩種方式
方式1:

public void sellTickets(){int i=4;synchronized(LockTest.class) {while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}}

方式2:

public static synchronized void sellTickets(){int i=4;while (i > 0) {i--;tickets--;System.out.println(Thread.currentThread().getName() + ":" + tickets);}}

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

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

相關文章

【MySQL】事務管理 -- 詳解

一、前言 CURD 不加控制,會有什么問題? CURD 滿足什么屬性,能解決上述問題? 買票的過程得是原子的。買票應該不能受互相的影響。買完票應該要永久有效。買前和買后都要是確定的狀態。 什么是事務? 事務就是一組 DML…

網絡編程作業day3

項目作業1&#xff1a;TCP機械臂測試 客戶端操作代碼&#xff1a; /*機械臂客戶端控制代碼*/ #include <myhead.h>#define SER_IP "192.168.125.176" //機械臂服務器IP地址 #define SER_PORT 8888 //機械臂服務器端口號 #define CLI_IP "…

Vue 項目重復點擊菜單刷新當前頁面

需求&#xff1a;“在當前頁面點擊當前頁面對應的菜單時&#xff0c;也能刷新頁面。” 由于 Vue 項目的路由機制是路由不變的情況下&#xff0c;對應的組件是不重新渲染的。所以重復點擊菜單不會改變路由&#xff0c;然后頁面就無法刷新了。 方案一 在vue項目中&#xff0c;…

深入了解 JavaScript 混淆加密和環境檢測

JavaScript混淆加密是一種通過修改代碼結構和命名約定來增加代碼的復雜性&#xff0c;使其難以被理解和逆向工程的技術。在這篇文章中&#xff0c;我們將深入探討JS混淆加密的一些邏輯&#xff0c;并介紹如何通過環境檢測來提高代碼的安全性。我們將使用案例代碼演示這些概念。…

List集合按中文拼音排序,或按自己想要順序的調整排序

1.你要按拼音排序&#xff08;字母同音依次比后面字母&#xff09; //集合按中文拼音排序Collections.sort(collect,new Comparator() {Overridepublic int compare(Object o1, Object o2) {return chineseCompare(o1,o2);}});//排序方法private static int chineseCompare(Obj…

【java】使用七牛云上傳文件

注冊七牛云 - 小王小王ii - 博客園 (cnblogs.com) 1.依賴 <dependencies><dependency><groupId>com.qiniu</groupId><artifactId>qiniu-java-sdk</artifactId><version>7.2.7</version></dependency><dependency>…

一些Springboot有用的配置:application.properties、xml訪問mybatis數據庫

application.properties #驅動類名稱 spring.datasource.driver-class-namecom.mysql.cj.jdbc.Driver #數據庫連接的url spring.datasource.urljdbc:mysql://localhost:3306/tlias #連接數據庫的用戶名 spring.datasource.usernameroot #連接數據庫的密碼 spring.datasource.p…

STM32用標準庫編寫按鍵控制LED燈的proteus仿真

首先打開proteus仿真軟件&#xff0c;繪制電路圖&#xff1a; 或是下載我已經建立好的工程修改&#xff1a; 鏈接&#xff1a;https://pan.baidu.com/s/1Nx5p3Tif6eHBIVkcPfsj9w?pwd1234 提取碼&#xff1a;1234 第一步復制整個工程文件夾&#xff0c;就不用重新配置的辛苦…

論文閱讀:2017MobileNet V1谷歌輕量化卷積神經網絡

拓展&#xff1a;賈揚清&#xff1a;深度學習框架caffe&#xff08;Convolutional Architecture for Fast Feature Embedding&#xff09; 主要貢獻&#xff1a; 深度可分離卷積&#xff08;Depthwise separable convolution&#xff09;逐點卷積&#xff08;Pointwise convo…

C++筆試題(選擇+編程)

個人主頁&#xff1a;Lei寶啊 愿所有美好如期而遇 選擇題 請找出下面程序中有哪些錯誤&#xff08;&#xff09; int main() {int i 10;int j 1;const int *p1;//(1)int const *p2 &i; //(2)p2 &j;//(3)int *const p3 &i;//(4)*p3 20;//(5)*p2 30;//(6…

LeetCode 刷題 [C++] 第279題.完全平方數

題目描述 給你一個整數 n &#xff0c;返回 和為 n 的完全平方數的最少數量 。 完全平方數是一個整數&#xff0c;其值等于另一個整數的平方&#xff1b;換句話說&#xff0c;其值等于一個整數自乘的積。例如&#xff0c;1、4、9 和 16 都是完全平方數&#xff0c;而 3 和 11…

#LLM入門|Prompt#2.7_檢查結果_Check_Outputs

引領你了解 如何評估系統生成的輸出。確保在向用戶展示輸出之前&#xff0c;對其質量、相關性和安全性進行嚴格的檢查&#xff0c;以保證我們提供的反饋是準確和適用的。如何運用審查(Moderation) API 來對輸出進行評估如何通過額外的 Prompt 提升模型在展示輸出之前的質量評估…

redis運維

1.備份redis配置文件 cp /etc/redis.conf /etc/redis.conf.bak 2.將redis中不要的注釋和空行刪除 sed -i /^#/d; /^$/d /etc/redis.conf 3.redis配置文件 bing 0.0.0.0 &#xff1a;綁定本機所有網卡 daemonize yes&#xff1a;設置后臺運行 requirepass redispwd…

k8s初始化錯誤

報錯詳情&#xff1a; you can check the kubelet logs for further clues by running: ‘journalctl -u kubelet’ Alternatively, there might be issues with your Kubernetes configuration files or maybe the necessary ports are not opened. Check the status of …

題目 1434: 藍橋杯歷屆試題-回文數字

題目描述: 觀察數字&#xff1a;12321&#xff0c;123321 都有一個共同的特征&#xff0c;無論從左到右讀還是從右向左讀&#xff0c;都是相同的。這樣的數字叫做&#xff1a;回文數字。 本題要求你找到一些5位或6位的十進制數字。滿足如下要求&#xff1a; 該數字的各個數位…

rust多個mod文件引用和文件夾mod使用注意事項

如果mod文件都在同一級目錄&#xff0c;則直接使用就可以&#xff0c;因為rust文件都是一個隱藏的mod&#xff0c;但是如果mod文件在另外一個目錄下面&#xff0c;就需要在目錄下面聲明一個mod.rs文件&#xff0c;這樣才能將那個目錄識別為一個mod&#xff0c;可以在mod.rs里面…

鴻蒙App開發新思路:小程序轉App

國家與國家之間錯綜復雜&#xff0c;在谷歌的安卓操作系統“斷供”后&#xff0c;鴻蒙系統的市場化&獨立化的道路便顯而易見了。 2024年1月18日&#xff0c;華為宣布&#xff0c;不再兼容安卓的“純血鴻蒙”--HarmonyOS NEXT鴻蒙星河版最終面世&#xff0c;并與2024年Q4正…

如何在阿里云/騰訊云Ubuntu服務器上安裝和配置GNOME桌面環境?

在Ubuntu服務器上安裝和配置GNOME桌面環境&#xff0c;首先需要確保已經安裝了必要的軟件和環境。以下是詳細的安裝和配置步驟&#xff1a; 安裝GNOME桌面環境&#xff1a; 使用命令sudo apt-get install gnome-shell來安裝GNOME桌面窗口管理程序。接著安裝gnome-panel、gnome-…

Flutter Text 下劃線

IntrinsicWidth(child: Column(mainAxisAlignment:MainAxisAlignment.center,children: [Text("工單名稱",style: TextStyle(overflow: TextOverflow.fade,color: AppColors.baseColor,fontSize: 15.sp,// decorationStyle: TextDecorationStyle.dashed),),Container…

馬士超:符合國際標準的沉浸式音頻HOLOSOUND的發展與未來 | 演講嘉賓公布

一、3D音頻 3D 音頻分論壇將于3月27日同期舉辦&#xff01; 3D音頻技術不僅能夠提供更加真實、沉浸的虛擬世界體驗&#xff0c;跨越時空的限制&#xff0c;探索未知的世界。同時&#xff0c;提供更加豐富、立體的情感表達和交流方式&#xff0c;讓人類能夠更加深入地理解彼此&a…