多執行緒學習筆記

2022-09-10 11:18:11 字數 4881 閱讀 8007

介紹多執行緒之前要介紹執行緒,介紹執行緒則離不開程序。

首先程序 :是乙個正在執行中的程式,每乙個程序執行都有乙個執行順序,該順序是乙個執行路徑,或者叫乙個控制單元;

執行緒:就是程序中的乙個獨立控制單元,執行緒在控制著程序的執行。乙個程序中至少有乙個程序。

多執行緒:乙個程序中不只有乙個執行緒。

為什麼要用多執行緒:

①、為了更好的利用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 testsleep 

public 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 interruptedexception 

4、停止執行緒---stop:

原stop方法因有缺陷已經停用了,那麼現在改如何停止執行緒?現在分享一種,就是讓run方法結束。

開啟多執行緒執行,執行的**通常是迴圈結構,只要控制住迴圈,就可以讓run方法結束,也就是執行緒結束。

5、設定優先順序:

每個執行緒執行時都有乙個優先順序的屬性,優先順序高的執行緒可以獲得較多的執行機會,而優先順序低的執行緒則獲得較少的執行機會。與執行緒休眠類似,執行緒的優先順序仍然無法保障線程的執行次序。只不過,優先順序高的執行緒獲取cpu資源的概率較大,優先順序低的也並非沒機會執行。

thread類中提供了優先順序的三個常量,**如下:

max_priority   =10

​min_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

finally }}

重點:synchronized與lock的對比

了解生產者消費者問題:處理方法:管程法、訊號燈法

10、執行緒池

多執行緒學習筆記 執行緒

thread類 常用屬性 currentthread 獲取當前正在執行的執行緒 isalive 指示當前執行緒的執行狀態 isbackground 指示是否為後台執行緒 isthreadpoolthread 指示是否屬於託管執行緒池 managedthreadid 獲取執行緒識別符號 name 獲取...

多執行緒學習筆記

多執行緒的相關概念 什麼是程序?當乙個程式開始執行時,它就是乙個程序,程序包括執行中的程式和程式所使用到的記憶體和系統資源。而乙個程序又是由多個執行緒所組成的。什麼是執行緒?執行緒是程式中的乙個執行流,每個執行緒都有自己的專有暫存器 棧指標 程式計數器等 但 區是共享的,即不同的執行緒可以執行同樣的...

多執行緒學習筆記

多執行緒是實現多工的一種方式,多個程序多個執行緒。建立執行緒 1.繼承thread類 子類覆蓋父類中的run方法,將執行緒執行的 存放在run中。2.建立子類物件的同時執行緒也被建立。3.通過呼叫start方法開啟執行緒。執行緒的各種狀態 1.建立狀態 在程式中用構造方法建立了乙個執行緒物件後,新的...