“簡單不先于復(fù)雜,而是在復(fù)雜之后.” —— Alan Perlis
大牛對多線程的理解:http://blog.csdn.net/dongmeng1994/article/details/54586466
首先:對于多線程,最簡單粗暴的理解:
就是同時(shí)執(zhí)行多個(gè)任務(wù).雖然狹義上講 在瞬間的時(shí)間內(nèi) CPU 還是只是執(zhí)行的一個(gè)任務(wù).一個(gè)沒使用多線程的程序就相當(dāng)于 只有一個(gè)主線程~ 打個(gè)比方你在吃飯 相當(dāng)于你只在吃饅頭..而多線程就是 你在同時(shí)吃很多東西. 比如 你啃了口饅頭后又喝了口水
一、程序與進(jìn)程
1、程序:一段靜態(tài)的代碼。
2、進(jìn)程:程序的一次動(dòng)態(tài)執(zhí)行過程,它對應(yīng)從代碼加載、執(zhí)行到執(zhí)行完畢的一個(gè)完整過程。
3、進(jìn)程也稱任務(wù),支持多個(gè)進(jìn)程同時(shí)執(zhí)行的OS就被稱為多進(jìn)程OS或多任務(wù)OS。
二、進(jìn)程與線程
在一個(gè)程序內(nèi)部也可以實(shí)現(xiàn)多個(gè)任務(wù)并發(fā)執(zhí)行,其中每個(gè)任務(wù)稱為線程。
線程是比進(jìn)程更小的執(zhí)行單位,它是在一個(gè)進(jìn)程中獨(dú)立的控制流,即程序內(nèi)部的控制流。
特點(diǎn):
線程不能獨(dú)立運(yùn)行,必須依賴于進(jìn)程,在進(jìn)程中運(yùn)行。
每個(gè)程序至少有一個(gè)線程稱為主線程。
單線程:只有一條線程的進(jìn)程稱為單線程
多線程:有不止一個(gè)線程的進(jìn)程稱為多線程
三、開啟多線程的優(yōu)點(diǎn)和缺點(diǎn)
提高界面程序響應(yīng)速度。通過使用線程,可以將需要大量時(shí)間完成的流程在后臺啟動(dòng)單獨(dú)的線程完成,提高前臺界面的相應(yīng)速度。
充分利用系統(tǒng)資源,提高效率。通過在一個(gè)程序內(nèi)部同時(shí)執(zhí)行多個(gè)流程,可以充分利用CPU等系統(tǒng)資源,從而最大限度的發(fā)揮硬件的性能。
當(dāng)程序中的線程數(shù)量比較多時(shí),系統(tǒng)將花費(fèi)大量的時(shí)間進(jìn)行線程的切換,這反而會(huì)降低程序的執(zhí)行效率。但是,相對于優(yōu)勢來說,劣勢還是很有限的,所以現(xiàn)在的項(xiàng)目開發(fā)中,多線程編程技術(shù)得到了廣泛的應(yīng)用。
多線程實(shí)現(xiàn)
一、在實(shí)現(xiàn)線程編程時(shí),首先需要讓一個(gè)類具備多線程的能力,繼承Thread類或?qū)崿F(xiàn)Runnable接口的類具備多線程的能力,然后創(chuàng)建線程對象,調(diào)用對應(yīng)的啟動(dòng)線程方法即可實(shí)現(xiàn)線程編程。
在一個(gè)程序中可以實(shí)現(xiàn)多個(gè)線程,多線程編程指在同一個(gè)程序中啟動(dòng)了兩個(gè)或兩個(gè)以上的線程。
在實(shí)際實(shí)現(xiàn)線程時(shí),Java語言提供了三種實(shí)現(xiàn)方式:
(1)繼承Thread類
(2)實(shí)現(xiàn)Runnable接口
(3)使用Timer和TimerTask組合
二、繼承Thread線程類實(shí)現(xiàn)多線程java.lang包中提供了一個(gè)專門的線程類(Thread),在該類中封裝了許多對線程進(jìn)行調(diào)度和處理的方法。如果一個(gè)類繼承了Thread類,則該類就具備了多線程的能力,可以多線程的方式執(zhí)行。
12345678910111213141516171819202122232425262728293031 class MyThread extends Thread{ public void run(){ //線程體 } } 繼承Thread類實(shí)現(xiàn)多線程。 MyThread tt1 = new MyThread (); //啟動(dòng)線程 tt1.start(); try{ for(int i = 0;i < 5;i++){ //延時(shí)1秒 Thread.sleep(1000); System.out.println("Main:" + i); } }catch(Exception e){}
注意:
線程的特性:隨機(jī)性,系統(tǒng)在執(zhí)行多線程程序時(shí)只保證線程是交替執(zhí)行的,至于哪個(gè)線程先執(zhí)行哪個(gè)線程后執(zhí)行,則無法獲得保證,需要書寫專門的代碼才可以保證執(zhí)行的順序。
對于同一個(gè)線程類,也可以啟動(dòng)多個(gè)線程
同一個(gè)線程不能啟動(dòng)兩次,
當(dāng)自定義線程中的run方法執(zhí)行完成以后,則自定義線程自然死亡。而對于系統(tǒng)線程來說,只有當(dāng)main方法執(zhí)行結(jié)束,而且啟動(dòng)的其它線程都結(jié)束以后,才會(huì)結(jié)束。當(dāng)系統(tǒng)線程執(zhí)行結(jié)束以后,程序的執(zhí)行才真正結(jié)束。
三、 實(shí)現(xiàn)Runable接口
a) 多線程對象實(shí)現(xiàn)java.lang.Runnable接口并且在該類中重寫Runnable接口的run方法。
b) 好處:實(shí)現(xiàn)Runable接口的方法避免了單繼承的局限性。
例1:使用實(shí)現(xiàn)Runable接口的方式實(shí)現(xiàn)多線程。
?1234567891011 class MyThread2 implements Runable{ public void run(){} //重寫Runable接口中的run()方法 } MyThread2 mt1=new MyThread2(); Thread t1=new Thread(mt1); t1.start();
線程的生命周期一、線程的生命周期
線程是一個(gè)動(dòng)態(tài)執(zhí)行的過程,它也有一個(gè)從產(chǎn)生到死亡的過程,這就是所謂的生命周期。一個(gè)線程在它的生命周期內(nèi)有5種狀態(tài):
1、新建(new Thread)
當(dāng)創(chuàng)建Thread類的一個(gè)實(shí)例(對象)時(shí),此線程進(jìn)入新建狀態(tài)(未被啟動(dòng))。例如:Thread t1=new Thread();
2、就緒(runnable)
線程已經(jīng)被啟動(dòng),正在等待被分配給CPU時(shí)間片,也就是說此時(shí)線程正在就緒隊(duì)列中排隊(duì)等候得到CPU資源。例如:t1.start();
3、運(yùn)行(running)
線程獲得CPU資源正在執(zhí)行任務(wù)(run()方法),此時(shí)除非此線程自動(dòng)放棄CPU資源或者有優(yōu)先級更高的線程進(jìn)入,線程將一直運(yùn)行到結(jié)束。
4、死亡(dead)
當(dāng)線程執(zhí)行完畢或被其它線程殺死,線程就進(jìn)入死亡狀態(tài),這時(shí)線程不可能再進(jìn)入就緒狀態(tài)等待執(zhí)行。
自然終止:正常運(yùn)行run()方法后終止
異常終止:調(diào)用stop()方法讓一個(gè)線程終止運(yùn)行
5、堵塞(blocked)
由于某種原因?qū)е抡谶\(yùn)行的線程讓出CPU并暫停自己的執(zhí)行,即進(jìn)入堵塞狀態(tài)。
正在睡眠:用sleep(long t) 方法可使線程進(jìn)入睡眠方式。一個(gè)睡眠著的線程在指定的時(shí)間過去可進(jìn)入就緒狀態(tài)。
正在等待:調(diào)用wait()方法。(調(diào)用motify()方法回到就緒狀態(tài))
被另一個(gè)線程所阻塞:調(diào)用suspend()方法。(調(diào)用resume()方法恢復(fù))
原文地址:http://jingyan.baidu.com/article/afd8f4de50289934e286e9d6.html