線程
線程作為排程和執行的機關,每個線程擁有獨立的運作棧和程式計數器
使用多線程的優點
1.
提高程式的響應。圖形化界面更有意義,可增強使用者體驗
2.
提高計算機系統cpu的使用率
3.
改善程式結構。将又長又複雜的程序分為多個線程,獨立執行,利于了解和修改
何時需要多線程
程式需要同時執行兩個或多個任務
程式需要試下哪一些需要等待的任務時,如使用者輸入,檔案讀寫操作
需要一些背景的程式時
//1.繼承Tread類
//2.重寫run方法
//3.建立對象調用start方法
//不能直接上使用 對象.run()調用線程;必須是 對象.start()
//不可以讓已經start()的線程 再去執行,會報異常(一個對象的start()隻能使用一次)
使用多線程,也可以采用匿名内部類的寫法
new Tread(){
@override
run(){
}
}.start();
4.
Thread類的常用方法
4.1 常用方法:
1.
start():啟動目前線程;調用目前線程的run(),隻有Thread類和他的子類才能調用start()方法
2.
run():
通常需要重寫Thread類中的此方法,将建立的線程要執行的操作聲明在此方法中
3.
currentThread():靜态方法,傳回執行目前代碼的線程
4.
getName():擷取目前線程的名字
5.
setName():設定目前線程的名字
6.
yield():釋放目前cpu的執行權
7.
join():線上程a中調用線程b的join(),此時線程a就進入阻塞狀态,直到線程b完全執行完以後,線程a才結束阻塞狀态。
8.
stop():已過時。當執行此方法時,強制結束目前線程。
9.
sleep(long
millitime):讓目前線程“睡眠”指定的millitime毫秒。在指定的millitime毫秒時間内,目前線程是阻塞狀态。1000毫秒等于1秒
10.isAlive():判斷目前線程是否存活
4.2 線程的優先級:
- MAX_PRIORITY:10
- MIN _PRIORITY:1
- NORM_PRIORITY:5 -->預設優先級
擷取和設定目前線程的優先級:
- getPriority():擷取線程的優先級
- setPriority(int p):設定線程的優先級
設定優先級在start()之前,并不是優先級高的執行完再執行優先級低的,隻是機率比較大而已
說明:高優先級的線程要搶占低優先級線程CPU的執行權。但是隻是從機率上講,高優先級的線程高機率的情況下被執行。并不意味着隻當高優先級的線程執行完以後,低優先級的線程才執行。
兩個方法:一個繼承Tread 一個實作Runnable
方式一:繼承Thread類的方式:
1.
建立一個繼承于Thread類的子類
2.
重寫Thread類的run() --> 将此線程執行的操作聲明在run()中
3.
建立Thread類的子類的對象
4.
通過此對象調用start():①啟動目前線程 ② 調用目前線程的run()
方式二:實作Runnable接口的方式:
1.
建立一個實作了Runnable接口的類
2.
實作類去實作Runnable中的抽象方法:run()
3.
建立實作類的對象
4.
将此對象作為參數傳遞到Thread類的構造器中,建立Thread類的對象
5.
通過Thread類的對象調用start(),調用了Runnable類型的target的run()方法
兩種方式的對比:
開發中優先選擇:實作Runnable接口的方式
原因:
1. 實作的方式沒類的單繼承性的局限性
2. 實作的方式更适合來處理多個線程共享資料的情況。
**聯系:**public class Thread implements Runnable
**相同點:**兩種方式都需要重寫run(),将線程要執行的邏輯聲明在run()中。 目前兩種方式,要想啟動線程,都是調用的Thread類中的start()。
- 問題:賣票過程中,出現了重票、錯票 -->出現了線程的安全問題
- 問題出現的原因:當某個線程操作車票的過程中,尚未操作完成時,其他線程參與進來,也操作車票。
- 如何解決:當一個線程a在操作ticket的時候,其他線程不能參與進來。直到線程a操作完ticket時,其他線程才可以開始操作ticket。這種情況即使線程a出現了阻塞,也不能被改變。