多線程實現(xiàn)方式及生命周期01

1、概念

基本概念
進程:就是電腦中一個一個的正在執(zhí)行的應(yīng)用程序;
線程:負責執(zhí)行這個程序的執(zhí)行單元;
單線程:效率低,但是安全;
多線程:效率高,但是數(shù)據(jù)不安全;

進程和線程的理解:
操作系統(tǒng)可以同時執(zhí)行多個任務(wù),每個任務(wù)就是進程;進程可以同時執(zhí)行多個任務(wù),每個任務(wù)就是線程。(通常一個任務(wù)就是一個程序,每個運行中的程序就是一個進程。一個程序運行時,內(nèi)部可能包含了多個順序執(zhí)行流,每個順序執(zhí)行流就是一個線程)

多線程的優(yōu)點:
1.進程之間不能共享內(nèi)存,但是線程之間共享內(nèi)存非常容易。
2.系統(tǒng)創(chuàng)建進程時需要為該進程重新分配系統(tǒng)資源,但創(chuàng)建線程代價小得多,因此使用多線程來實現(xiàn)多任務(wù)并發(fā)比多進程的效率高。
3.Java語言內(nèi)置了多線程功能支持,而不是單純地作為底層操作系統(tǒng)的調(diào)度方式,簡化了Java的多線程編程。

2、多線程實現(xiàn)方式

方式一:
1、自定義一個繼承Thread類,重寫run()方法;
2、創(chuàng)建Thread子類對象,調(diào)用start()方法,開啟線程;
使用繼承Thread類的方法創(chuàng)建線程類時,多個線程之間無法共享線程類的成員變量(子類定義的成員變量)。

方式二:推薦使用
1、自定義一個類,實現(xiàn)Runnable接口,重寫run()方法;
2、創(chuàng)建Thread對象,創(chuàng)建該類對象, 通過Thread類構(gòu)造方法,把該類對象傳進去;
3、調(diào)用Thread類的start()方法開啟線程;
實現(xiàn)Runnable接口的方式,多個線程可以共享同一個線程類的成員變量。

方式三:使用Callable和Future創(chuàng)建線程

創(chuàng)建線程的三種方式對比(實現(xiàn)接口和繼承Thread類):
實現(xiàn)Runnable或Callable接口創(chuàng)建多線程
優(yōu)點:
1.線程類只是實現(xiàn)了接口,還可以繼承其他的類;
2.多個線程可以共享同一個target對象,非常適合多個線程來處理同一份資源的情況,從而可以將CPU、代碼和數(shù)據(jù)分開,形成清晰地模型,較好地體現(xiàn)了面向?qū)ο蟮乃枷耄?br> 缺點:
1.編程稍微復雜,如果需要訪問當前線程,則必須使Thread.currentThread()方法;

繼承Thread類創(chuàng)建多線程:
優(yōu)點:編寫簡單,如果需要訪問當前線程,直接 使用this可以獲得當前線程;
缺點:不能再繼承其他父類;

3、線程的生命周期

新建:使用new關(guān)鍵字創(chuàng)建一個線程;
此時,僅僅Java虛擬機為其分配內(nèi)存,并初始化其成員變量的值。

就緒:調(diào)用start()方法后,線程處于就緒狀態(tài),等待獲取CPU的使用權(quán)。
此時,具備了執(zhí)行條件,不具備執(zhí)行權(quán)利。

運行:就緒狀態(tài)的線程得到CPU的使用權(quán)后,進入運行狀態(tài)。
此時,具備了執(zhí)行條件,具備了執(zhí)行權(quán)利。

等待:運行狀態(tài)下的線程,調(diào)用thread類中的wait()方法,線程進入等待狀態(tài)。
此時,必須調(diào)用thread類中的notify()方法才能被喚醒,喚醒后處于就緒狀態(tài)。

休眠:運行狀態(tài)下的線程,調(diào)用thread類中的sleep()方法,則會進入休眠狀態(tài)。休眠時間結(jié)束后,進入就緒狀態(tài);

阻塞:運行狀態(tài)下的線程,發(fā)出輸入/輸出請求時,線程進入阻塞狀態(tài),等待輸入/輸出結(jié)束時線程進入就緒狀態(tài)。對于阻塞的線程,即使系統(tǒng)資源空閑,線程依然不能回到運行狀態(tài)。

死亡:三種情況:
1.當線程的run()方法或call()方法執(zhí)行完畢后,線程進入死亡狀態(tài)。
2.線程拋出一個未捕獲的Exception或Error
3.直接調(diào)用該線程的stop()方法來結(jié)束該線程。(該方法容易導致死鎖,不推薦使用)

Note:不能對一個已經(jīng)死亡的線程調(diào)用start()方法使他重新啟動,死亡就是死亡,該線程將不可能再次作為線程執(zhí)行。對死亡的線程調(diào)用start()方法或?qū)π聞?chuàng)建的線程兩次調(diào)用start()方法,會引發(fā)IllegalThreadStateException異常;

//當線程在同步代碼塊中,sleep()和wait()的區(qū)別就很明顯。


clipboard.png

4、同步方法和同步代碼塊

同步方法:(使用同步方法可以非常方便地實現(xiàn)線程安全的類)
用synchronized關(guān)鍵字修飾的方法,作用是每次只允許一條線程進入方法執(zhí)行代碼;
靜態(tài)同步方法:本類的字節(jié)碼對象;
非靜態(tài)同步方法:無須顯示指定同步監(jiān)視器,同步方法的監(jiān)視器是this,也就是調(diào)用該方法的對象。

同步代碼塊:
一個用synchronized關(guān)鍵字修飾的代碼塊,這個代碼塊中的代碼是被鎖住的代碼,每次只允許一條線程來執(zhí)行;
必須確保同步代碼塊的鎖對象唯一;//所對象為被訪問的共享資源作為同步監(jiān)視器。

synchronized(obj){
//此處的代碼就是同步代碼塊
}

其中,obj是同步監(jiān)視器,代碼的含義是:線程開始執(zhí)行同步代碼塊之前,必須先獲得對同步監(jiān)視器的鎖定。任何時刻只能有一個線程可以獲得對同步監(jiān)視器的鎖定,當同步代碼塊執(zhí)行完成后,該線程會釋放對該同步監(jiān)視器的鎖定。

同步監(jiān)視器的目的:阻止兩個線程對同一個共享資源進行并發(fā)訪問。因此通常使用可能被并發(fā)訪問的共享資源充當同步監(jiān)視器。

線程安全的類具有如下特征:
該類的對象可以被多個線程安全地訪問。
每個線程調(diào)用該對象的任意方法之后都可以得到正確結(jié)果;

可變類和不可變類:
不可變類總是線程安全的,因為它的對象狀態(tài)不可改變,但可變對象需要額外的方法來保證其線程安全。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    勝浩_ae28閱讀 5,257評論 0 23
  • 進程和線程 進程 所有運行中的任務(wù)通常對應(yīng)一個進程,當一個程序進入內(nèi)存運行時,即變成一個進程.進程是處于運行過程中...
    小徐andorid閱讀 2,988評論 3 53
  • ??一個任務(wù)通常就是一個程序,每個運行中的程序就是一個進程。當一個程序運行時,內(nèi)部可能包含了多個順序執(zhí)行流,每個順...
    OmaiMoon閱讀 1,803評論 0 12
  • Java多線程學習 [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 3,107評論 1 18
  • 本文主要講了java中多線程的使用方法、線程同步、線程數(shù)據(jù)傳遞、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等。 首先講...
    李欣陽閱讀 2,596評論 1 15

友情鏈接更多精彩內(nèi)容