2020久久超碰欧美精品最新亚洲欧美日韩久久精品,国产福利电影一区二区三区,亚洲欧美日韩一区在线观看,亚洲国产欧美日韩欧美特级,亚洲欧美日韩成人一区久久,欧美日韩精品一区二区三区不卡,国产欧美日韩va另类影音先锋,亚洲欧美日韩久久精品,亚洲欧美日韩国产成人精品影院,亚洲国产欧美日韩精品一区二区三区,欧美日韩国产成人高清视频,日韩久久精品国产免费观看频道,久久人人爽人人爽从片av高清,国产精品综合一区二区

首頁技術文章正文

Java培訓之同步

更新時間:2017-06-30 來源:黑馬程序員Java培訓學院 瀏覽量:

好處:解決了線程安全問題。
弊端:相對降低性能,因為判斷鎖需要消耗資源,產生了死鎖。
 
定義同步是有前提的:
1,必須要有兩個或者兩個以上的線程,才需要同步。
2,多個線程必須保證使用的是同一個鎖。
 
java培訓項目實戰中,同步的第二種表現形式:
同步函數:其實就是將同步關鍵字定義在函數上,讓函數具備了同步性。
 
同步函數是用的哪個鎖呢?
通過驗證,函數都有自己所屬的對象this,所以同步函數所使用的鎖就是this鎖。
 
當同步函數被static修飾時,這時的同步用的是哪個鎖呢?
靜態函數在加載時所屬于類,這時有可能還沒有該類產生的對象,但是該類的字節碼文件加載進內存就已經被封裝成了對象,這個對象就是該類的字節碼文件對象。
所以靜態加載時,只有一個對象存在,那么靜態同步函數就使用的這個對象。
這個對象就是 類名.class
在java培訓項目實戰中 
同步代碼塊和同步函數的區別?
同步代碼塊使用的鎖可以是任意對象。
同步函數使用的鎖是this,靜態同步函數的鎖是該類的字節碼文件對象。
 
在一個類中只有一個同步,可以使用同步函數。如果有多同步,必須使用同步代碼塊,來確定不同的鎖。所以同步代碼塊相對靈活一些。
-------------------------------------------------------
★考點問題:請寫一個延遲加載的單例模式?寫懶漢式;當出現多線程訪問時怎么解決?加同步,解決安全問題;效率高嗎?不高;怎樣解決?通過雙重判斷的形式解決。
//懶漢式:延遲加載方式。
當多線程訪問懶漢式時,因為懶漢式的方法內對共性數據進行多條語句的操作。所以容易出現線程安全問題。為了解決,加入同步機制,解決安全問題。但是卻帶來了效率降低。
為了效率問題,通過雙重判斷的形式解決。
class Single{
private static Single s = null;
private Single(){}
public static Single getInstance(){ //鎖是誰?字節碼文件對象;
if(s == null){
synchronized(Single.class){
if(s == null)
s = new Single();
}
}
return s;
}
}
---------------------------------------------------------
同步死鎖:通常只要將同步進行嵌套,就可以看到現象。同步函數中有同步代碼塊,同步代碼塊中還有同步函數。
 java培訓實戰項目中
線程間通信:思路:多個線程在操作同一個資源,但是操作的動作卻不一樣。
1:將資源封裝成對象。
2:將線程執行的任務(任務其實就是run方法。)也封裝成對象。
 
等待喚醒機制:涉及的方法:
wait:將同步中的線程處于凍結狀態。釋放了執行權,釋放了資格。同時將線程對象存儲到線程池中。
notify:喚醒線程池中某一個等待線程。
notifyAll:喚醒的是線程池中的所有線程。
 
注意:
1:這些方法都需要定義在同步中。 
2:因為這些方法必須要標示所屬的鎖。
你要知道 A鎖上的線程被wait了,那這個線程就相當于處于A鎖的線程池中,只能A鎖的notify喚醒。
3:這三個方法都定義在Object類中。為什么操作線程的方法定義在Object類中?
因為這三個方法都需要定義同步內,并標示所屬的同步鎖,既然被鎖調用,而鎖又可以是任意對象,那么能被任意對象調用的方法一定定義在Object類中。
 
wait和sleep區別: 分析這兩個方法:從執行權和鎖上來分析:
wait:可以指定時間也可以不指定時間。不指定時間,只能由對應的notify或者notifyAll來喚醒。
sleep:必須指定時間,時間到自動從凍結狀態轉成運行狀態(臨時阻塞狀態)。
wait:線程會釋放執行權,而且線程會釋放鎖。
Sleep:線程會釋放執行權,但不是不釋放鎖。
 
線程的停止:通過stop方法就可以停止線程。但是這個方式過時了。
停止線程:原理就是:讓線程運行的代碼結束,也就是結束run方法。
怎么結束run方法?一般run方法里肯定定義循環。所以只要結束循環即可。
第一種方式:定義循環的結束標記。
第二種方式:如果線程處于了凍結狀態,是不可能讀到標記的,這時就需要通過Thread類中的interrupt方法,將其凍結狀態強制清除。讓線程恢復具備執行資格的狀態,讓線程可以讀到標記,并結束。
 
---------< java.lang.Thread >----------
interrupt():中斷線程。
setPriority(int newPriority):更改線程的優先級。
getPriority():返回線程的優先級。
toString():返回該線程的字符串表示形式,包括線程名稱、優先級和線程組。
Thread.yield():暫停當前正在執行的線程對象,并執行其他線程。
setDaemon(true):將該線程標記為守護線程或用戶線程。將該線程標記為守護線程或用戶線程。當正在運行的線程都是守護線程時,Java 虛擬機退出。該方法必須在啟動線程前調用。
join:臨時加入一個線程的時候可以使用join方法。
當A線程執行到了B線程的join方式。A線程處于凍結狀態,釋放了執行權,B開始執行。A什么時候執行呢?只有當B線程運行結束后,A才從凍結狀態恢復運行狀態執行。


本文版權歸黑馬程序員Java培訓學院所有,歡迎轉載,轉載請注明作者出處。謝謝!

作者:黑馬程序員Java培訓學院

首發:http://java.itheima.com/



分享到:
在線咨詢 我要報名
和我們在線交談!