java Thread的start和run方法的区别
一、認(rèn)識(shí)Thread的 start() 和 run()
概述:
t.start()會(huì)導(dǎo)致run()方法被調(diào)用,run()方法中的內(nèi)容稱(chēng)為線(xiàn)程體,它就是這個(gè)線(xiàn)程需要執(zhí)行的工作。
用start()來(lái)啟動(dòng)線(xiàn)程,實(shí)現(xiàn)了真正意義上的啟動(dòng)線(xiàn)程,此時(shí)會(huì)出現(xiàn)異步執(zhí)行的效果,即在線(xiàn)程的創(chuàng)建和啟動(dòng)中所述的隨機(jī)性。
而如果使用run()來(lái)啟動(dòng)線(xiàn)程,就不是異步執(zhí)行了,而是同步執(zhí)行,不會(huì)達(dá)到使用線(xiàn)程的意義
1.start():
我們先來(lái)看看API中對(duì)于該方法的介紹:
“Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.”?
“start()方法會(huì)使得該線(xiàn)程開(kāi)始執(zhí)行;java虛擬機(jī)會(huì)去調(diào)用該線(xiàn)程的run()方法。”
???? 使該線(xiàn)程開(kāi)始執(zhí)行;Java 虛擬機(jī)調(diào)用該線(xiàn)程的?run?方法。
???? 結(jié)果是兩個(gè)線(xiàn)程并發(fā)地運(yùn)行;當(dāng)前線(xiàn)程(從調(diào)用返回給?start?方法)和另一個(gè)線(xiàn)程(執(zhí)行其?run?方法)。
???? 多次啟動(dòng)一個(gè)線(xiàn)程是非法的。特別是當(dāng)線(xiàn)程已經(jīng)結(jié)束執(zhí)行后,不能再重新啟動(dòng)。
用start方法來(lái)啟動(dòng)線(xiàn)程,真正實(shí)現(xiàn)了多線(xiàn)程運(yùn)行,這時(shí)無(wú)需等待run方法體代碼執(zhí)行完畢而直接繼續(xù)執(zhí)行下面的代碼。通過(guò)調(diào)
用Thread類(lèi)的 start()方法來(lái)啟動(dòng)一個(gè)線(xiàn)程,這時(shí)此線(xiàn)程處于就緒(可運(yùn)行)狀態(tài),并沒(méi)有運(yùn)行,一旦得到cpu時(shí)間片,就開(kāi)始
執(zhí)行run()方法,這里方法 run()稱(chēng)為線(xiàn)程體,它包含了要執(zhí)行的這個(gè)線(xiàn)程的內(nèi)容,Run方法運(yùn)行結(jié)束,此線(xiàn)程隨即終止。
?
2.run():
public class Thread extends Object implements Runnable我們還是先看看API中對(duì)該方法的介紹:
????? 如果該線(xiàn)程是使用獨(dú)立的?Runnable?運(yùn)行對(duì)象構(gòu)造的,則調(diào)用該?Runnable?對(duì)象的?run?方法;否則,該方法不執(zhí)行任何操作并返回。
??? Thread?的子類(lèi)應(yīng)該重寫(xiě)該方法。
run()方法只是類(lèi)的一個(gè)普通方法而已,如果直接調(diào)用Run方法,程序中依然只有主線(xiàn)程這一個(gè)線(xiàn)程,其程序執(zhí)行路徑還是只有
一條,還是要順序執(zhí)行,還是要等待run方法體執(zhí)行完畢后才可繼續(xù)執(zhí)行下面的代碼,這樣就沒(méi)有達(dá)到寫(xiě)線(xiàn)程的目的。
?
3.總結(jié)
調(diào)用start方法方可啟動(dòng)線(xiàn)程,而run方法只是thread的一個(gè)普通方法調(diào)用,還是在主線(xiàn)程里執(zhí)行。
二、代碼實(shí)例:
?通過(guò)start啟動(dòng)線(xiàn)程,異步啟動(dòng)
public?static?void?main(String args[]) {Thread t = new?Thread() {public?void?run() {pong();}};t.start();System.out.print("ping");}static?void?pong() {System.out.print("pong");}輸出結(jié)果: pingpong
?
通過(guò)run啟動(dòng)線(xiàn)程,同步啟動(dòng)
public?static?void?main(String args[]) {Thread t = new?Thread() {public?void?run() {pong();}};t.run();System.out.print("ping");}static?void?pong() {System.out.print("pong");}輸出結(jié)果:pongping
?
通過(guò)以上兩個(gè)程序?qū)嵗?#xff0c;可以很容易的區(qū)分出start()方法和run()方法的區(qū)別:
t.start(); 該行代碼相當(dāng)于是啟動(dòng)線(xiàn)程,異步操作
t.run(); 該行代碼相當(dāng)于是使用t這個(gè)類(lèi)中的run方法而已,只是主線(xiàn)程的一個(gè)普通的方法
三、線(xiàn)程狀態(tài)說(shuō)明:
線(xiàn)程狀態(tài)從大的方面來(lái)說(shuō),可歸結(jié)為:初始狀態(tài)、可運(yùn)行狀態(tài)、不可運(yùn)行狀態(tài)和消亡狀態(tài),說(shuō)明如下:
1)線(xiàn)程的實(shí)現(xiàn)有兩種方式,一是繼承Thread類(lèi),二是實(shí)現(xiàn)Runnable接口,但不管怎樣,當(dāng)我們new了thread實(shí)例后,線(xiàn)程就進(jìn)入了初始狀態(tài);
2)當(dāng)該對(duì)象調(diào)用了start()方法,就進(jìn)入可運(yùn)行狀態(tài);
3)進(jìn)入可運(yùn)行狀態(tài)后,當(dāng)該對(duì)象被操作系統(tǒng)選中,獲得CPU時(shí)間片就會(huì)進(jìn)入運(yùn)行狀態(tài);
4)進(jìn)入運(yùn)行狀態(tài)后情況就比較多,大致有如下情形:
? ? ? ?a.?run()方法或main()方法結(jié)束后,線(xiàn)程就進(jìn)入終止?fàn)顟B(tài);
? ? ? ?b. 當(dāng)線(xiàn)程調(diào)用了自身的sleep()方法或其他線(xiàn)程的join()方法,就會(huì)進(jìn)入阻塞狀態(tài)(該狀態(tài)既停止當(dāng)前線(xiàn)程,但并不釋放
所占有的資源)。當(dāng)sleep()結(jié)束或join()結(jié)束后,該線(xiàn)程進(jìn)入可運(yùn)行狀態(tài),繼續(xù)等待OS分配時(shí)間片; 當(dāng)線(xiàn)程剛進(jìn)入可運(yùn)行
狀態(tài)(注意,還沒(méi)運(yùn)行),發(fā)現(xiàn)將要調(diào)用的資源被鎖牢(synchroniza,lock),將會(huì)立即進(jìn)入鎖池狀態(tài),等待獲取鎖標(biāo)記(這時(shí)
的鎖池里也許已經(jīng)有了其他線(xiàn)程在等待獲取鎖標(biāo)記,這時(shí)它們處于隊(duì)列狀態(tài),既先到先得),一旦線(xiàn)程獲得鎖標(biāo)記后,就
轉(zhuǎn)入可運(yùn)行狀態(tài),等待OS分配 CPU時(shí)間片;
? ? ? ? c. 當(dāng)線(xiàn)程調(diào)用wait()方法后會(huì)進(jìn)入等待隊(duì)列(進(jìn)入這個(gè)狀態(tài)會(huì)釋放所占有的所有資源,與阻塞狀態(tài)不同),進(jìn)入這個(gè)狀
態(tài)后,是不能自動(dòng)喚醒的,必須依靠其他線(xiàn)程調(diào)用notify()或notifyAll()方法才能被喚醒(由于notify()只是喚醒一個(gè)線(xiàn)程,
但我們由不能確定具體喚醒的是哪一個(gè)線(xiàn)程,也許我們需要喚醒的線(xiàn)程不能夠被喚醒,因此在實(shí)際使用時(shí),一般都用
notifyAll()方法,喚醒有所線(xiàn)程),線(xiàn)程被喚醒后會(huì)進(jìn)入鎖池,等待獲取鎖標(biāo)記。 當(dāng)線(xiàn)程調(diào)用stop方法,即可使線(xiàn)程進(jìn)入消
亡狀態(tài),但是由于stop方法是不安全的,不鼓勵(lì)使用,大家可以通過(guò)run方法里的條件變通實(shí)現(xiàn)線(xiàn)程的 stop。
總結(jié)
以上是生活随笔為你收集整理的java Thread的start和run方法的区别的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java.lang.RuntimeExc
- 下一篇: Python爬虫之xlml解析库