介紹多執行緒之前要介紹執行緒,介紹執行緒則離不開程序。
首先程序 :是乙個正在執行中的程式,每乙個程序執行都有乙個執行順序,該順序是乙個執行路徑,或者叫乙個控制單元;
執行緒:就是程序中的乙個獨立控制單元,執行緒在控制著程序的執行。乙個程序中至少有乙個程序。
多執行緒:乙個程序中不只有乙個執行緒。
為什麼要用多執行緒:
①、為了更好的利用cpu的資源,如果只有乙個執行緒,則第二個任務必須等到第乙個任務結束後才能進行,如果使用多執行緒則在主線程執行任務的同時可以執行其他任務,而不需要等待;
②、程序之間不能共享資料,執行緒可以;
③、系統建立程序需要為該程序重新分配系統資源,建立執行緒代價比較小;
④、j**a語言內建了多執行緒功能支援,簡化了j**a多執行緒程式設計。
1、 繼承thread類 重寫run()方法 呼叫start開啟執行緒
public class testthread1 extends thread}public static void main(string args) }}
2、 實現runnable介面重寫run()方法 呼叫start開啟執行緒
public class testthread2 implements runnable}public static void main(string args) }}
3、通過callable和future建立執行緒:
實現步驟:①、建立callable介面的實現類,並實現call()方法,改方法將作為執行緒執行體,且具有返回值。
②、建立callable實現類的例項,使用futruetask類進行包裝callable物件,futuretask物件封裝了callable物件的call()方法的返回值
③、使用futuretask物件作為thread物件啟動新執行緒。
④、呼叫futuretask物件的get()方法獲取子執行緒執行結束後的返回值。
四、繼承thread類和實現runnable介面、實現callable介面的區別。
繼承thread:執行緒**存放在thread子類run方法中。
優勢:編寫簡單,可直接用this.getname()獲取當前執行緒,不必使用thread.currentthread()方法。
劣勢:已經繼承了thread類,無法再繼承其他類。
實現runnable:執行緒**存放在介面的子類的run方法中。
優勢:避免了單繼承的侷限性、多個執行緒可以共享乙個target物件,非常適合多執行緒處理同乙份資源的情形。
劣勢:比較複雜、訪問執行緒必須使用thread.currentthread()方法、無返回值。
實現callable:
優勢:有返回值、避免了單繼承的侷限性、多個執行緒可以共享乙個target物件,非常適合多執行緒處理同乙份資源的情形。
劣勢:比較複雜、訪問執行緒必須使用thread.currentthread()方法
建議使用實現介面的方式建立多執行緒。
五、執行緒狀態管理
1、執行緒睡眠---sleep
執行緒睡眠的方法(兩個):sleep(long millis)在指定的毫秒數內讓正在執行的執行緒休眠。
sleep(long millis,int nanos)在指定的毫秒數加指定的納秒數內讓正在執行的執行緒休眠。
public class testsleeppublic static void tendown() throws interruptedexception }
}}
2、執行緒讓步---yield:
該方法和sleep方法類似,也是thread類提供的乙個靜態方法,可以讓正在執行的執行緒暫停,但是不會進入阻塞狀態,而是直接進入就緒狀態。相當於只是將當前執行緒暫停一下,然後重新進入就緒的執行緒池中,讓執行緒排程器重新排程一次。也會出現某個執行緒呼叫yield方法後暫停,但之後排程器又將其排程出來重新進入到執行狀態。
public class testyield}class yielddemo implements runnable}}
}}
sleep和yield的區別:
①、sleep方法宣告丟擲interruptedexception,呼叫該方法需要捕獲該異常。yield沒有宣告異常,也無需捕獲。
②、sleep方法暫停當前執行緒後,會進入阻塞狀態,只有當睡眠時間到了,才會轉入就緒狀態。而yield方法呼叫後 ,是直接進入就緒狀態。
3、執行緒合併---join:
當b執行緒執行到了a執行緒的.join()方法時,b執行緒就會等待,等a執行緒都執行完畢,b執行緒才會執行。
join可以用來臨時加入執行緒執行。
public static void main(string args) throws interruptedexception4、停止執行緒---stop:
原stop方法因有缺陷已經停用了,那麼現在改如何停止執行緒?現在分享一種,就是讓run方法結束。
開啟多執行緒執行,執行的**通常是迴圈結構,只要控制住迴圈,就可以讓run方法結束,也就是執行緒結束。
5、設定優先順序:
每個執行緒執行時都有乙個優先順序的屬性,優先順序高的執行緒可以獲得較多的執行機會,而優先順序低的執行緒則獲得較少的執行機會。與執行緒休眠類似,執行緒的優先順序仍然無法保障線程的執行次序。只不過,優先順序高的執行緒獲取cpu資源的概率較大,優先順序低的也並非沒機會執行。
thread類中提供了優先順序的三個常量,**如下:
max_priority =10min_priority =1
norm_priority =5
public static void main(string args)}class mypriority implements runnable
}
注意的地方,只是對執行緒設定優先順序,優先順序高的不一定先執行
6、守護執行緒(daemon)
執行緒分為使用者執行緒和守護執行緒
虛擬機器必須確保使用者執行緒執行完畢
虛擬機器不用等待守護執行緒執行完畢
如,後台記錄操作日誌,監控記憶體,垃圾**等待。
7、執行緒同步與鎖
併發:同乙個物件被多個執行緒同時操作
列子:上萬人同時搶100張票、兩個銀行同時取錢。
public static void main(string args) }class mysyn implements runnable catch (interruptedexception e)
system.out.println(thread.currentthread().getname() + " " + tick--);}}
}}
同步方法1:
同步函式:就是用synchronize關鍵字修飾的方法。因為每個j**a物件都有乙個內建鎖,當用synchronize關鍵字修飾方法時內建鎖會保護整個方法,而在呼叫該方法之前,要先獲得內建鎖,否則就會處於阻塞狀態,預設鎖的是this。
**演示:請將上方**的第17行改為以下**↓
public synchronized void run()總結:}
同步的前提:
1、必須要有兩個或者兩個以上的執行緒。
2、必須是多個執行緒使用同乙個鎖。
3、必須保證同步中只能有乙個執行緒在執行。
4、只能同步方法,不能同步變數和類。
5、不必同步類中所有方法,類可以擁有同步和非同步的方法。
6、如果乙個執行緒在物件上獲得乙個鎖,就沒有任何其他執行緒可以進入(該物件的)類中的任何乙個同步方法。
7、執行緒睡眠時,它所持的任何鎖都不會釋放。
好處:解決了多執行緒的安全問題。
弊端:多個執行緒需要判斷,消耗資源,降低效率。
如何找問題?
1、明確哪些**是多執行緒執行**。
2、明確共享資料。
3、明確多執行緒執行**中哪些語句是操作共享資料的。
8、死鎖
程序a中包含資源a,程序b中包含資源b,a的下一步需要資源b,b的下一步需要資源a,所以它們就互相等待對方占有的資源釋放,所以也就產生了乙個迴圈等待死鎖。
死鎖形成的必要條件總結(都滿足之後就會產生):
①、互斥條件:資源不能被共享,只能被同乙個程序使用;
②、請求與保持條件:已經得到資源的程序可以申請新的資源;
③、非剝奪條件:已經分配的資源不能從相應的程序中強制剝奪;
④、迴圈等待條件:系統中若干程序形成環路,該環路中每個程序都在等待相鄰程序占用的資源。
9、lock鎖
reentrantlock類實現了lock,它擁有與synchronized相同的並發現和記憶體語義,在實現執行緒安全的控制中,比較常用的是 reentrantlock,可以顯式加鎖、釋放鎖。
class a重點:synchronized與lock的對比finally }}
了解生產者消費者問題:處理方法:管程法、訊號燈法
10、執行緒池
多執行緒學習筆記 執行緒
thread類 常用屬性 currentthread 獲取當前正在執行的執行緒 isalive 指示當前執行緒的執行狀態 isbackground 指示是否為後台執行緒 isthreadpoolthread 指示是否屬於託管執行緒池 managedthreadid 獲取執行緒識別符號 name 獲取...
多執行緒學習筆記
多執行緒的相關概念 什麼是程序?當乙個程式開始執行時,它就是乙個程序,程序包括執行中的程式和程式所使用到的記憶體和系統資源。而乙個程序又是由多個執行緒所組成的。什麼是執行緒?執行緒是程式中的乙個執行流,每個執行緒都有自己的專有暫存器 棧指標 程式計數器等 但 區是共享的,即不同的執行緒可以執行同樣的...
多執行緒學習筆記
多執行緒是實現多工的一種方式,多個程序多個執行緒。建立執行緒 1.繼承thread類 子類覆蓋父類中的run方法,將執行緒執行的 存放在run中。2.建立子類物件的同時執行緒也被建立。3.通過呼叫start方法開啟執行緒。執行緒的各種狀態 1.建立狀態 在程式中用構造方法建立了乙個執行緒物件後,新的...