一媚狰、擴(kuò)展java.lang.Thread類
1.?
進(jìn)程:每個進(jìn)程都有獨(dú)立的代碼和數(shù)據(jù)空間(進(jìn)程上下文),進(jìn)程間的切換會有較大的開銷,一個進(jìn)程包含1--n個線程甚纲。 線程:同一類線程共享代碼和數(shù)據(jù)空間朦前,每個線程有獨(dú)立的運(yùn)行棧和程序計(jì)數(shù)器(PC)介杆,線程切換開銷小【麓纾 線程和進(jìn)程一樣分為五個階段:創(chuàng)建春哨、就緒、運(yùn)行恩伺、阻塞赴背、終止。 多進(jìn)程是指操作系統(tǒng)能同時運(yùn)行多個任務(wù)(程序)凰荚∪脊郏 多線程是指在同一程序中有多個順序流在執(zhí)行
2.
start()方法的調(diào)用后并不是立即執(zhí)行多線程代碼,而是使得該線程變?yōu)榭蛇\(yùn)行態(tài)(Runnable)便瑟,什么時候運(yùn)行是由操作系統(tǒng)決定的缆毁。 start方法重復(fù)調(diào)用的話,會出現(xiàn)java.lang.IllegalThreadStateException異常到涂。
二脊框、實(shí)現(xiàn)java.lang.Runnable接口
class Thread2 implements Runnable{
String name;
public void Thread2(String name){
this.name = name;
}
@Override
public void run() {
for (int i = 0; i < 5; i++) {
System.out.println(name + "運(yùn)行? :? " + i);
try {
Thread.sleep((int) Math.random() * 10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class main{
public static void main(String[] arge){
new Thread2(new Thread2("C")).start();
new Thread2(new Thread2("D")).start();
}
}
Thread2類通過實(shí)現(xiàn)Runnable接口,使得該類有了多線程類的特征践啄。run()方法是多線程程序的一個約定浇雹。所有的多線程代碼都在run方法里面。Thread類實(shí)際上也是實(shí)現(xiàn)了Runnable接口的類往核。
在啟動的多線程的時候箫爷,需要先通過Thread類的構(gòu)造方法Thread(Runnable target) 構(gòu)造出對象,然后調(diào)用Thread對象的start()方法來運(yùn)行多線程代碼聂儒。
實(shí)際上所有的多線程代碼都是通過運(yùn)行Thread的start()方法來運(yùn)行的虎锚。因此,不管是擴(kuò)展Thread類還是實(shí)現(xiàn)Runnable接口來實(shí)現(xiàn)多線程衩婚,最終還是通過Thread的對象的API來控制線程的窜护,熟悉Thread類的API是進(jìn)行多線程編程的基礎(chǔ)。
三.Thread和Runnable的區(qū)別
實(shí)現(xiàn)Runnable接口比繼承Thread類所具有的優(yōu)勢:
1):適合多個相同的程序代碼的線程去處理同一個資源
2):可以避免java中的單繼承的限制
3):增加程序的健壯性非春,代碼可以被多個線程共享柱徙,代碼和數(shù)據(jù)獨(dú)立
四、線程狀態(tài)轉(zhuǎn)換
1奇昙、新建狀態(tài)(New):新創(chuàng)建了一個線程對象护侮。
2、就緒狀態(tài)(Runnable):線程對象創(chuàng)建后储耐,其他線程調(diào)用了該對象的start()方法羊初。該狀態(tài)的線程位于可運(yùn)行線程池中,變得可運(yùn)行什湘,等待獲取CPU的使用權(quán)长赞。
3、運(yùn)行狀態(tài)(Running):就緒狀態(tài)的線程獲取了CPU闽撤,執(zhí)行程序代碼得哆。
4、阻塞狀態(tài)(Blocked):阻塞狀態(tài)是線程因?yàn)槟撤N原因放棄CPU使用權(quán)哟旗,暫時停止運(yùn)行贩据。直到線程進(jìn)入就緒狀態(tài)栋操,才有機(jī)會轉(zhuǎn)到運(yùn)行狀態(tài)。阻塞的情況分三種:
(一)乐设、等待阻塞:運(yùn)行的線程執(zhí)行wait()方法讼庇,JVM會把該線程放入等待池中。
(二)近尚、同步阻塞:運(yùn)行的線程在獲取對象的同步鎖時蠕啄,若該同步鎖被別的線程占用,則JVM會把該線程放入鎖池中戈锻。
(三)歼跟、其他阻塞:運(yùn)行的線程執(zhí)行sleep()或join()方法,或者發(fā)出了I/O請求時格遭,JVM會把該線程置為阻塞狀態(tài)哈街。當(dāng)sleep()狀態(tài)超時、join()等待線程終止或者超時拒迅、或者I/O處理完畢時骚秦,線程重新轉(zhuǎn)入就緒狀態(tài)。
5璧微、死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法作箍,該線程結(jié)束生命周期。