------- <a href="http://www.itheima.com" target="blank">android培訓</a>、<a href="http://www.itheima.com" target="blank">java培訓</a>、期待與您交流! ----------
多線程:
創建一個線程的第一種方式:繼承Thread類。
步驟:
1.定義類繼承Thread.
2.重寫Thread類中的run 方法。
3.調用線程的start 方法。
該方法有兩個作用:啓動線程,調用run 方法。
Thread類用於描述線程,
它定義了一個功能,用於存儲線程要運行的代碼。該存儲功能就是run 方法。
創建一個線程的第二種方式:繼承Runnable接口。
兩種方法的區別:
繼承Thread:線程代碼存放在Thread子類的run方法中。
實現Runnable:線程代碼存放在接口子類的run方法中。
多線程的安全問題:
當多條語句在操作同一線程共享數據時,一個線程對多條語句只執行了一部分,還沒有執行完另一個線程參與進來執行。
解決方法:
對多條操作共享數據的語句,只能讓一個線程都執行完,在執行過程中,其他線程不可以參與執行。
Java對於多線程的安全問題提供了專業的解決方案:
就是同步代碼塊
Synchronized(對象){
需要被同步的代碼
}
火車上的衛生間——經典(同步鎖)
同步的前提:
1、必須要有兩個或者兩個以上的線程。
2、必須是多個線程使用同一個鎖。
必須保證同步中只能有一個線程在運行。
優點:解決了線程的安全問題
弊端:多個線程都需要判斷鎖,較消耗資源,
同步函數所使用的鎖是this
同步函數被靜態修飾後使用的鎖是該方法所在類的字節碼文件對象。類名.class
單例設計模式
懶漢式與餓漢式單例設計模式的不同:
懶漢式:
它的特點是實例的延遲加載,但是存在問題如果多線程訪問時會出現安全問題,可以加同步來解決,加同步的方式:可以用同步代碼塊兒但稍微有些低效,用雙重判斷的方式可以解決效率問題,加同步的時候使用的鎖是:該類所屬的字節碼文件對象。
餓漢式:
public class Single {
//餓漢式
private static final Single single=new Single();
private Single(){}
public static synchronized Single getInstance(){
return single;
}
//懶漢式
private static Single single=null;
private Single(){}
public static Single getInstance(){
if(single==null){
synchronized(Single.class){
if(single==null){
single=new Single();
}
}
}
return single;
}
}
死鎖:同步中嵌套同步但鎖不同。
當用線程寫生產者消費者(多個生產者,多個消費者)時必須用while循環和notifalyAll();
JDK1.5中提供了(顯示的鎖機制及顯示的鎖對象上的等待喚醒操作機制)多線程升級解決方案。將同步synchronized替換成現實Lock操作。將Object 中的wait,notify ,notifyAll替換成了Condition對象,該對象可以Lock鎖進行獲取。它實現了本方只喚醒對方操作。(生產者消費者有什麼替換方案?)
Stop方法已經過時,停止線程只有一種讓run方法結束,開啓多線程運行的代碼通常是循環結構,只要控制住循環,就可以讓run方法結束,即線程結束。
特殊情況:
當線程處於凍結狀態,就不會讀取到標記,那麼線程就不會結束,當沒有指定的方式讓凍結的線程恢復到運行狀態時,需要對凍結進行清除,強制讓線程恢復到運行狀態中來。這樣就可以操作標記讓線程結束。
Thread類提供該方法 interrupt();
Join:
當A線程執行到了B線程的.join()方法時,A就會等待。等B線程都執行完,A纔會執行,join可以用來臨時加入線程執行!