synchronized同步鎖

在多線程的情況下,由于同一進程的多個線程共享同一片存儲空間,在帶來方便的同時,也帶來了訪問沖突這個嚴重的問題。Java語言提供了專門機制以解決這種沖突,有效避免了同一個數據對象被多個線程同時訪問。
由于我們可以通過 private 關鍵字來保證數據對象只能被方法訪問,所以我們只需針對方法提出一套機制,這套機制就是 synchronized 關鍵字,它包括兩種用法:synchronized 方法和 synchronized 塊。
1. synchronized 方法:通過在方法聲明中加入 synchronized關鍵字來聲明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制對類成員變量的訪問:每個類實例對應一把鎖,每個 synchronized 方法都必須獲得調用該方法的類實例的鎖方能執行,否則所屬線程阻塞,方法一旦執行,就獨占該鎖,直到從該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得該鎖,重新進入可執行狀態。這種機制確保了同一時刻對于每一個類實例,其所有聲明為 synchronized 的成員函數中至多只有一個處于可執行狀態(因為至多只有一個能夠獲得該類實例對應的鎖),從而有效避免了類成員變量的訪問沖突(只要所有可能訪問類成員變量的方法均被聲明為 synchronized)。
在 Java 中,不光是類實例,每一個類也對應一把鎖,這樣我們也可將類的靜態成員函數聲明為 synchronized ,以控制其對類的靜態成員變量的訪問。
synchronized 方法的缺陷:若將一個大的方法聲明為synchronized 將會大大影響效率,典型地,若將線程類的方法 run() 聲明為 synchronized ,由于在線程的整個生命期內它一直在運行,因此將導致它對本類任何 synchronized 方法的調用都永遠不會成功。當然我們可以通過將訪問類成員變量的代碼放到專門的方法中,將其聲明為 synchronized ,并在主方法中調用來解決這一問題,但是 Java 為我們提供了更好的解決辦法,那就是 synchronized 塊。
2. synchronized 塊:通過 synchronized關鍵字來聲明synchronized 塊。語法如下:
synchronized(syncObject) {
//允許訪問控制的代碼
}
synchronized 塊是這樣一個代碼塊,其中的代碼必須獲得對象 syncObject (如前所述,可以是類實例或類)的鎖方能執行,具體機制同前所述。由于可以針對任意代碼塊,且可任意指定上鎖的對象,故靈活性較高。

public?class?TraditionalThreadSynchronized? {
?????
????public?static?void?main(String[] args) {
????????new?TraditionalThreadSynchronized().init();
????}
????void?init(){
????????final?Outputer out? = new?Outputer();
????????//線程1
????????new?Thread(new?Runnable(){
????????????@Override
????????????public?void?run() {
????????????????while(true){
????????????????????try?{
????????????????????????Thread.sleep(200);
????????????????????} catch?(InterruptedException e) {
????????????????????????e.printStackTrace();
????????????????????}
????????????????????out.output1("Tmethod--->AAAAAA");
????????????????}
????????????}
??????????????
????????}).start();
????????//線程2
????????new?Thread(new?Runnable(){
????????????@Override
????????????public?void?run() {
????????????????while(true){
????????????????????try?{
????????????????????????Thread.sleep(200);
????????????????????} catch?(InterruptedException e) {
????????????????????????e.printStackTrace();
????????????????????}
????????????????????out.output3("Tmethod--->BBBBBB");
????????????????}
????????????}
?????????????
????????}).start();
????} //end main
?????
????static?class?Outputer{? //內部類
????????/**
?????????* 方法內部加上線程鎖,線程的鎖只能鎖同一個對象,如果有static方法那么線程鎖必須為Class,不能為this
?????????*/
????????public?void?output1(String name){
????????????int?len =name.length();
????????????synchronized?(Outputer.class){ //synchronized參數可以為this,但是和static方法不能實現互斥,實現互斥只能為同一個對象
????????????????for(int?i=0;i<len;i++){
????????????????????System.out.print(name.charAt(i));
????????????????}
????????????????System.out.println();
????????????}
????????}
????????/**
?????????* output2 和 output3不能實現同步,output2用的是對象鎖的是this而output3是static方法要鎖的話只能用class,如:output1
?????????* @param name
?????????*/
????????public?synchronized?void?output2(String name){ //直接把鎖加在方法上,默認把synchronized加載方法上那么他的互斥對象為this
????????????int?len =name.length();
????????????????for(int?i=0;i<len;i++){
????????????????????System.out.print(name.charAt(i));
????????????????}
????????????????System.out.println();
????????}
????????//static方法的線程鎖
????????public?static?synchronized?void?output3(String name){
????????????int?len =name.length();
????????????for(int?i=0;i<len;i++){
????????????????System.out.print(name.charAt(i));
????????????}
????????????System.out.println();
????????}
????}
}

轉載于:https://www.cnblogs.com/dyc-cfc/p/4256304.html

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

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

相關文章

c++ socket學習(1.3)

本文學習相關資料&#xff1a; C/C socket編程教程 環境&#xff1a;vs2015 源碼&#xff1a;本文代碼 在這里c socket學習&#xff08;1.1&#xff09;學到了怎么樣建立TCP&#xff0c;然后通過TCP連接發送、接收信息。 但是都是一次性的&#xff0c;當時是接收信息后就結束…

一個一線城市的IT白領的生活成本:3萬/年

自從大學畢業&#xff0c;經濟獨立&#xff0c;就開始全面統計各種生活開支。仔細的去統計下&#xff0c;發現開銷還是挺大的。 定理&#xff1a;開銷越大&#xff0c;就意味著你每個月的收入必須越高。 三族鼎立節余族: 收入-開支 > 0月光族&#xff1a;收入-開支 0透支族…

android 編譯共享ccache的緩存

1. android自帶的ccache版本號(2.4版本號)過低&#xff0c;是無法支持以上的功能的&#xff0c;須要使用新版ccache。2. 最新的ccache請到http://ccache.samba.org/download.html下載3. 下載解壓之后&#xff0c;在linux底下進入ccache文件夾&#xff0c;執行:./configure./mak…

一位軟件工程師的6年總結

作者&#xff1a;成曉旭 “又是一年畢業時”&#xff0c;看到一批批學子離開人生的象牙塔&#xff0c;走上各自的工作崗位&#xff1b;想想自己也曾經意氣風發、躊躇滿志&#xff0c;不覺感嘆萬千……本文是自己工作6年的經 歷沉淀或者經驗提煉&#xff0c;希望對所有的軟件工…

c++ socket學習(1.4)

本文學習相關資料&#xff1a; C/C socket編程教程 環境&#xff1a;vs2015 源碼&#xff1a;本文代碼 前面學到了TCP怎么循環發包&#xff0c;但是TCP連接的話會出現一個問題粘包。 TCP連接接收到的數據并不是馬上讀取到內存里面的&#xff0c;而是放在緩沖區&#xff0c;讓…

mongodb中分頁顯示數據集的學習

mongodb中分頁顯示數據集的學習 這次繼續看mongodb中的分頁。首先依然是插入數據&#xff1a; 1&#xff09; db.Blog.insert( { name : "Denis", age : 20, city : "Princeton" } ) db.Blog.insert( { name : "Abe", age : 30, city : &quo…

學習編程,英語很重要!!

學會編程&#xff0c;可能不需要英語多好&#xff0c;但是學號編程&#xff0c;英語真的很重要&#xff01;&#xff01;&#xff01; 好多文檔&#xff0c;demo全是英文的&#xff0c;蛋疼&#xff0c;應許需要學習&#xff01;&#xff01;&#xff01;轉載于:https://www.cn…

c++ socket學習(1.5)

本文學習相關資料&#xff1a; C/C socket編程教程 環境&#xff1a;vs2015 源碼&#xff1a;本文代碼 這次來試一下使用TCP來傳輸文件&#xff0c;其實傳輸數據和差不多&#xff0c;就是多一個讀取文件&#xff0c;和一個寫文件而已。 服務端 int readlan 100; std::ifst…

matlab生成HEX文件-任意信號 大于64K長度

HEX文件格式不贅述&#xff0c;寫里直接放上代碼。請批評改正。 1 %%convert a signal data into hex file format2 % data format:16bit 3 % signal length: less than 2^24-14 % author: Yang Li yangli0534gmail.com5 % data:2015.01.276 7 clear all;8 close all;9 clc; 10…

移動端網頁中ViewPort的使用

<meta name"viewport" content"widthdevice-width,target-densitydpihigh-dpi, initial-scale1.0, minimum-scale1.0, maximum-scale1.0, user-scalableno"> <meta name”viewport” content”widthdevice-width, initial-scale1.0, user-scalabl…

c++ socket學習(1.6)

本文學習相關資料&#xff1a; C/C socket編程教程 環境&#xff1a;vs2015 源碼&#xff1a;本文代碼 這次來看看UDP 之前在c socket學習&#xff08;1.2&#xff09;講過UDP怎么發送了&#xff0c;那現在來做一個可以一直發送的。 這次沒有什么接收端和發送端了&#xff0…

redis學習筆記——(1)

1. NoSQL&Redis介紹 NoSQL&#xff0c;Not Only SQL&#xff0c;是非關系型的數據庫。傳統的關系數據庫不能滿足超大規模和高并發的應用。 是以Key-Value的形式存儲&#xff0c;&#xff08;例如JSON,XML&#xff09;&#xff0c;不一定遵循傳統數據庫的一些基本要求&#…

命令模式堅決svn樹沖突(local unversioned, incoming add upon update)

當工作目錄修改刪除過時更新使用svn更新就容易發生樹沖突“Tree Confilict”.會出現類似提示。 local unversioned, incoming add upon update1local unversioned,incoming add upon update如果使用圖形化客戶端可以通過對比文件和解決沖突按鈕進行解決&#xff0c; 如果是使用…

c++ vector學習

參考資料&#xff1a; cppreference.com 本文代碼&#xff1a; 本文源碼 目錄隱式成員函數1.operator &#xff08;賦值給容器&#xff09;2.assign &#xff08;將值賦給容器&#xff09;元素訪問3.at &#xff08;訪問指定元素&#xff0c;進行下標檢查&#xff09;4.operat…

linux關閉聲音

對于CentOS/Redhat/RHEL/Fedora系統&#xff0c;使用root身份執行&#xff1a;echo "alias pcspkr off" >> /etc/modprobe.conf轉載于:https://www.cnblogs.com/keethebest/p/3434821.html

Bundle Identifier

Bundle Identifier : 產品的唯一標識符 1.在模擬器上面&#xff0c;只能有一個唯一的標識符的應用程序 2.在AppStore上&#xff0c;所有的應用程序的Bundler ID都是唯一的 Bundle ID 公司的反向域名 產品名 Bundle ID 不支持中文&#xff0c;因此如果是上架產品&#xff0c;需…

c++ array學習

參考資料&#xff1a; cppreference.com 本文代碼&#xff1a; 本文源碼 array和vector的區別是array是和C中的數組類似&#xff0c;不能動態改變數組大小&#xff0c;所以會比vector少很多函數。 目錄隱式定義的成員函數1.operator &#xff08;將另一個容器拷貝過來&#x…

lucene4入門(2)搜索

歡迎轉載http://www.cnblogs.com/shizhongtao/p/3440479.html 接著上一篇&#xff0c;這里繼續搜索&#xff0c;對于搜索和創建一樣&#xff0c;首先你要確定搜索位置&#xff0c;然后用規定的類來讀取。還要注意一點&#xff0c;確定分詞器&#xff0c;因為不同的分詞器所創建…

Topcoder SRM 648 (div.2)

第一次做TC全部通過&#xff0c;截圖紀念一下。 終于藍了一次&#xff0c;也是TC上第一次變成藍名&#xff0c;下次就要做Div.1了&#xff0c;希望div1不要掛零。。。_(:зゝ∠)_ A. KitayutaMart2 萬年不變的水題。 #include<cstdio> #include<cstring> #include&…

Kadane's algorithm學習

Kadane’s algorithm 簡單來說就是用來計算數組中的連續子數組之和最大是多少 vector<int> vec; int temp 0,ans 0; for(int i0;i<vec.size();i){temp max(tempvec[i],vec[i]);ans max(temp,ans); } return ans;循環的第一行就是用來比較當前位置的值和前面數組…