學(xué)習(xí)記錄之多線程
線程:一個順序的單一的程序執(zhí)行流程就是一個線程。代碼一句一句的有先后順序的執(zhí)行
多線程:多個單一順序執(zhí)行的流程并發(fā)運行。造成"感官上同時運行"的效果。
并發(fā):多個線程實際運行是走走停停的。線程調(diào)度程序會將CPU運行時間劃分為若干個時間片段并盡可能均勻的分配給每個線程,拿到時間片的線程被CPU執(zhí)行這段時間。當(dāng)超時后線程調(diào)度程序會再次分配一個時間片段給一個線程使得CPU執(zhí)行它。如此反復(fù)。由于CPU執(zhí)行時間在納秒級別,我們感覺不到切換線程運行的過程。所以微觀上走走停停,宏觀上感覺一起運行
的現(xiàn)象成為并發(fā)運行!
用途: 當(dāng)出現(xiàn)多個代碼片段執(zhí)行順序有沖突時,希望它們各干各的時就應(yīng)當(dāng)放在不同線程上"同時"運行
- 一個線程可以運行,但是多個線程可以更快時,可以使用多線程運行
線程的生命周期圖

創(chuàng)建線程有兩種方式
方式一:繼承Thread并重寫run方法
定義一個線程類,重寫run方法,在其中定義線程要執(zhí)行的任務(wù)(希望和其他線程并發(fā)執(zhí)行的任務(wù))。
注:啟動該線程要調(diào)用該線程的start方法,而不是run方法?。?!
第一種創(chuàng)建線程的方式
優(yōu)點:
在于結(jié)構(gòu)簡單,便于匿名內(nèi)部類形式創(chuàng)建。
缺點:
1:直接繼承線程,會導(dǎo)致不能在繼承其他類去復(fù)用方法,這在實際開發(fā)中是非常不便的。
2:定義線程的同時重寫了run方法,會導(dǎo)致線程與線程任務(wù)綁定在了一起,不利于線程的重用。
方式二:實現(xiàn)Runnable接口單獨定義線程任務(wù)
匿名內(nèi)部類形式的線程創(chuàng)建
java中的代碼都是靠線程運行的,執(zhí)行main方法的線程稱為"主線程"。
線程提供了一個方法:
static Thread currentThread()
該方法可以獲取運行這個方法的線程
線程API
獲取線程相關(guān)信息的方法
線程優(yōu)先級
線程start后會納入到線程調(diào)度器中統(tǒng)一管理,線程只能被動的被分配時間片并發(fā)運行,而無法主動索取時間片.線程調(diào)度器盡可能均勻的將時間片分配給每個線程.
線程有10個優(yōu)先級,使用整數(shù)1-10表示
1為最小優(yōu)先級,10為最高優(yōu)先級.5為默認(rèn)值
調(diào)整線程的優(yōu)先級可以最大程度的干涉獲取時間片的幾率.優(yōu)先級越高的線程獲取時間片的次數(shù)越多,反之則越少.
sleep阻塞
線程提供了一個靜態(tài)方法:
static void sleep(long ms)
使運行該方法的線程進入阻塞狀態(tài)指定的毫秒,超時后線程會自動回到RUNNABLE狀態(tài)等待再次獲取時間片并發(fā)運行.
sleep方法處理異常:InterruptedException.
當(dāng)一個線程調(diào)用sleep方法處于睡眠阻塞的過程中,該線程的interrupt()方法被調(diào)用時,sleep方法會拋出該異常從而打斷睡眠阻塞.
守護線程也稱為:后臺線程
????守護線程是通過普通線程調(diào)用setDaemon(boolean on)方法設(shè)置而來的,因此創(chuàng)建上與普通線程無異.
????守護線程的結(jié)束時機上有一點與普通線程不同,即:進程的結(jié)束.
????進程結(jié)束:當(dāng)一個進程中的所有普通線程都結(jié)束時,進程就會結(jié)束,此時會殺掉所有正在運行的守護線程.
常當(dāng)我們不關(guān)心某個線程的任務(wù)什么時候停下來,它可以一直運行,但是程序主要的工作都結(jié)束時它應(yīng)當(dāng)跟著結(jié)束時,這樣的任務(wù)就適合放在守護線程上執(zhí)行.比如GC就是在守護線程上運行的.
多線程并發(fā)安全問題:
????當(dāng)多個線程并發(fā)操作同一臨界資源,由于線程切換時機不確定,導(dǎo)致操作臨界資源的順序出現(xiàn)混亂嚴(yán)重時可能導(dǎo)致系統(tǒng)癱瘓.
臨界資源:操作該資源的全過程同時只能被單個線程完成.
synchronized關(guān)鍵字
synchronized有兩種使用方式
- 在方法上修飾,此時該方法變?yōu)橐粋€同步方法
- 同步塊,可以更準(zhǔn)確的鎖定需要排隊的代碼片段
當(dāng)一個方法使用synchronized修飾后,這個方法稱為"同步方法",即:多個線程不能同時 在方法內(nèi)部執(zhí)行.只能有先后順序的一個一個進行. 將并發(fā)操作同一臨界資源的過程改為同步執(zhí)行就可以有效的解決并發(fā)安全問題.
同步塊:
有效的縮小同步范圍可以在保證并發(fā)安全的前提下盡可能的提高并發(fā)效率.同步塊可以更準(zhǔn)確的控制需要多個線程排隊執(zhí)行的代碼片段.
語法:
同步監(jiān)視器對象即上鎖的對象,要想保證同步塊中的代碼被多個線程同步運行,則要求多個線程看到的同步監(jiān)視器對象是同一個.
在靜態(tài)方法上使用synchronized:
當(dāng)在靜態(tài)方法上使用synchronized后,該方法是一個同步方法.由于靜態(tài)方法所屬類,所以一定具有同步效果.
靜態(tài)方法使用的同步監(jiān)視器對象為當(dāng)前類的類對象(Class的實例).
靜態(tài)方法中使用同步塊時,指定的鎖對象通常也是當(dāng)前類的類對象
互斥鎖:
當(dāng)多個線程執(zhí)行不同的代碼片段,但是這些代碼片段之間不能同時運行時就要設(shè)置為互斥的.
使用synchronized鎖定多個代碼片段,并且指定的同步監(jiān)視器是同一個時,這些代碼片段之間就是互斥的.