Java線程一

在現(xiàn)在的Hotspot VM中,當(dāng)調(diào)用了Java線程對象的start方法就會創(chuàng)建一個操作系統(tǒng)線程,該操作系統(tǒng)線程就屬于可供CPU調(diào)度的線程了甥郑,此時一個Java線程對象就與一個操作系統(tǒng)線程一一對應(yīng)逃魄。當(dāng)然,這只是HotSpot VM中線程的實現(xiàn)方式澜搅,其他JVM可有不同的實現(xiàn)伍俘。

一般說來,通過Java創(chuàng)建一個可供CPU調(diào)度的線程有兩種方式:

1店展、創(chuàng)建一個java.lang.Thread對象养篓,并調(diào)用其start方法秃流;

2赂蕴、通過本地方法(如JNI)創(chuàng)建本地線程并加入的VM中。

線程的概述(Introduction)

線程是一個程序的多個執(zhí)行路徑舶胀,執(zhí)行調(diào)度的單位概说,依托于進程存在。 線程不僅可以共享進程的內(nèi)存嚣伐,而且還擁有一個屬于自己的內(nèi)存空間糖赔,這段內(nèi)存空間也叫做線程棧,是在建立線程時由系統(tǒng)分配的轩端,主要用來保存線程內(nèi)部所使用的數(shù)據(jù)放典,如線程執(zhí)行函數(shù)中所定義的變量。

注意:Java中的多線程是一種搶占機制而不是分時機制。搶占機制指的是有多個線程處于可運行狀態(tài)奋构,但是只允許一個線程在運行壳影,他們通過競爭的方式搶占CPU

?線程的定義(Defining)

定義一個線程(Defining a Thread)有兩種方法

1) 繼承java.lang.Thread類

/*** 使用繼承java.lang.Thread類的方式創(chuàng)建一個線程*/

publicclassThreadTestextendsThread {/*** 重寫(Override)run()方法 JVM會自動調(diào)用該方法/

publicvoidrun() {System.out.println("I'm running!");}}

注意:重寫(override)run()方法在該線程的start()方法被調(diào)用后弥臼,JVM會自動調(diào)用run方法來執(zhí)行任務(wù)宴咧;但是重載(overload)run()方法,該方法和普通的成員方法一樣径缅,并不會因調(diào)用該線程的start()方法而被JVM自動運行掺栅。 例如:

publicclassThreadTestextendsThread {/*** 重寫(Override)run()方法 JVM會自動調(diào)用該方法/

@Override?publicvoidrun() {System.out.println("I'm running!");}

/*** 重載(Overload)run()方法 和普通的方法一樣,并不會在該線程的start()方法被調(diào)用后被JVM自動運行*/

publicvoidrun(inttimes) {System.out.println("I'm running!(Overload)");}}

不建議使用此方法定義線程纳猪,因為采用繼承Thread的方式定義線程后氧卧,你不能在繼承其他的類了,導(dǎo)致程序的可擴展性大大降低兆旬。

2) 實現(xiàn)java.lang.Runnable接口

/*** 通過實現(xiàn)Runnable接口創(chuàng)建一個線程*/

publicclassThreadTestimplementsRunnable {publicvoidrun() {System.out.println("I'm running!");}}

?線程的啟動(Starting)

任何一個線程的執(zhí)行的前提都是必須有Thread class的實例存在假抄,并且通過調(diào)用run()方法啟動線程。

1)如果線程是繼承Thread類丽猬,則創(chuàng)建方式如下:

ThreadTest1 tt =newThreadTest1();tt.start();

2)如果是實現(xiàn)Runnable接口宿饱,則創(chuàng)建方式如下:

ThreadTest2 tt =newThreadTest2();Thread t =newThread(tt);t.start();

?線程的狀態(tài)(State)

新生狀態(tài)(New):當(dāng)一個線程的實例被創(chuàng)建即使用new關(guān)鍵字和Thread類或其子類創(chuàng)建一個線程對象后,此時該線程處于新生(new)狀態(tài)谬以,處于新生狀態(tài)的線程有自己的內(nèi)存空間由桌,但該線程并沒有運行,此時線程還不是活著的(not alive)行您;

就緒狀態(tài)(Runnable):通過調(diào)用線程實例的start()方法來啟動線程使線程進入就緒狀態(tài)(runnable);處于就緒狀態(tài)的線程已經(jīng)具備了運行條件炕檩,但還沒有被分配到CPU即不一定會被立即執(zhí)行捌斧,此時處于線程就緒隊列,等待系統(tǒng)為其分配CPCU妇押,等待狀態(tài)并不是執(zhí)行狀態(tài); 此時線程是活著的(alive)敲霍;

運行狀態(tài)(Running):一旦獲取CPU(被JVM選中),線程就進入運行(running)狀態(tài)肩杈,線程的run()方法才開始被執(zhí)行;在運行狀態(tài)的線程執(zhí)行自己的run()方法中的操作屯换,直到調(diào)用其他的方法而終止与学、或者等待某種資源而阻塞、或者完成任務(wù)而死亡晕窑;如果在給定的時間片內(nèi)沒有執(zhí)行結(jié)束卵佛,就會被系統(tǒng)給換下來回到線程的等待狀態(tài);此時線程是活著的(alive)疾牲;

阻塞狀態(tài)(Blocked):通過調(diào)用join()衙解、sleep()、wait()或者資源被暫用使線程處于阻塞(blocked)狀態(tài)蚓峦;處于Blocking狀態(tài)的線程仍然是活著的(alive)

死亡狀態(tài)(Dead):當(dāng)一個線程的run()方法運行完畢或被中斷或被異常退出,該線程到達死亡(dead)狀態(tài)霍转。此時可能仍然存在一個該Thread的實例對象一汽,當(dāng)該Thready已經(jīng)不可能在被作為一個可被獨立執(zhí)行的線程對待了,線程的獨立的call stack已經(jīng)被dissolved沾谓。一旦某一線程進入Dead狀態(tài)戳鹅,他就再也不能進入一個獨立線程的生命周期了昏兆。對于一個處于Dead狀態(tài)的線程調(diào)用start()方法,會出現(xiàn)一個運行期(runtime exception)的異常隶债;處于Dead狀態(tài)的線程不是活著的(not alive)。

*********************************************線程狀態(tài)圖 ***********************************

Key

?線程的方法(Method)瞒滴、屬性(Property)

1)優(yōu)先級(priority)

每個類都有自己的優(yōu)先級赞警,一般property用1-10的整數(shù)表示,默認優(yōu)先級是5世剖,優(yōu)先級最高是10笤虫;優(yōu)先級高的線程并不一定比優(yōu)先級低的線程執(zhí)行的機會高,只是執(zhí)行的機率高酬凳;默認一個線程的優(yōu)先級和創(chuàng)建他的線程優(yōu)先級相同遭庶;

2)Thread.sleep()/sleep(long millis)

當(dāng)前線程睡眠/millis的時間(millis指定睡眠時間是其最小的不執(zhí)行時間,因為sleep(millis)休眠到達后台诗,無法保證會被JVM立即調(diào)度)赐俗;sleep()是一個靜態(tài)方法(static method) ,所以他不會停止其他的線程也處于休眠狀態(tài)阻逮;線程sleep()時不會失去擁有的對象鎖。 作用:保持對象鎖事哭,讓出CPU瓜富,調(diào)用目的是不讓當(dāng)前線程獨自霸占該進程所獲取的CPU資源,以留一定的時間給其他線程執(zhí)行的機會谤辜;

3)Thread.yield()

讓出CPU的使用權(quán),給其他線程執(zhí)行機會丑念、讓同等優(yōu)先權(quán)的線程運行(但并不保證當(dāng)前線程會被JVM再次調(diào)度、使該線程重新進入Running狀態(tài))渔彰,如果沒有同等優(yōu)先權(quán)的線程推正,那么yield()方法將不會起作用。

4)thread.join()

使用該方法的線程會在此調(diào)用線程的run方法執(zhí)行完畢后再往下繼續(xù)執(zhí)行舔稀。

讓一個線程等待另一個線程完成才繼續(xù)執(zhí)行,A 線程線程執(zhí)行體中調(diào)用B 線程 的join方法产园,則A 線程被阻塞夜郁,直到線程B 執(zhí)行完畢,A 才得以繼續(xù)執(zhí)行屎即。

5)object.wait()

當(dāng)一個線程執(zhí)行到wait()方法時事富,他就進入到一個和該對象相關(guān)的等待池(Waiting Pool)中,同時失去了對象的機鎖—暫時的雕擂,wait后還要返還對象鎖當(dāng)前線程必須擁有當(dāng)前對象的鎖井赌,如果當(dāng)前線程不是此鎖的擁有者贵扰,會拋出IllegalMonitorStateException異常,所以wait()必須在synchronized block中調(diào)用。

6)object.notify()/notifyAll()

喚醒在當(dāng)前對象等待池中等待的第一個線程/所有線程纹坐。notify()/notifyAll()也必須擁有相同對象鎖列肢,否則也會拋出IllegalMonitorStateException異常。

7)Synchronizing Block

Synchronized Block/方法控制對類成員變量的訪問拴还;Java中的每一個對象都有唯一的一個內(nèi)置的鎖欧聘,每個Synchronized Block/方法只有持有調(diào)用該方法被鎖定對象的鎖才可以訪問,否則所屬線程阻塞怀骤;機鎖具有獨占性、一旦被一個Thread持有弓摘,其他的Thread就不能再擁有(不能訪問其他同步方法)痕届,方法一旦執(zhí)行,就獨占該鎖锤窑,直到從該方法返回時才將鎖釋放,此后被阻塞的線程方能獲得該鎖渊啰,重新進入可執(zhí)行狀態(tài)申屹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末哗讥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子忌栅,更是在濱河造成了極大的恐慌,老刑警劉巖湖员,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件娘摔,死亡現(xiàn)場離奇詭異,居然都是意外死亡凳寺,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門逆趋,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晒奕,“玉大人,你說我怎么就攤上這事脑慧。” “怎么了坑律?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵囊骤,是天一觀的道長。 經(jīng)常有香客問我藕各,道長,這世上最難降的妖魔是什么激况? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任乌逐,我火速辦了婚禮,結(jié)果婚禮上浙踢,老公的妹妹穿的比我還像新娘灿渴。我一直安慰自己,他們只是感情好蹬挤,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布棘幸。 她就那樣靜靜地躺著,像睡著了一般吨悍。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上育瓜,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天爆雹,我揣著相機與錄音愕鼓,去河邊找鬼。 笑死菇晃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的磺送。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼崇呵,長吁一口氣:“原來是場噩夢啊……” “哼域慷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起犹褒,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤叠骑,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后宙枷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茧跋,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年璧帝,在試婚紗的時候發(fā)現(xiàn)自己被綠了富寿。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锣夹。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡银萍,死狀恐怖恤左,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情飞袋,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布瓶您,位于F島的核電站纲仍,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏郑叠。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一寇僧、第九天 我趴在偏房一處隱蔽的房頂上張望署拟。 院中可真熱鬧,春花似錦推穷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至议谷,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間芬首,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工赦政, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恢着。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓财破,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狈究。 傳聞我的和親對象是個殘疾皇子盏求,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Java多線程學(xué)習(xí) [-] 一擴展javalangThread類 二實現(xiàn)javalangRunnable接口 三T...
    影馳閱讀 2,959評論 1 18
  • 本文主要講了java中多線程的使用方法磅废、線程同步、線程數(shù)據(jù)傳遞拯勉、線程狀態(tài)及相應(yīng)的一些線程函數(shù)用法、概述等宫峦。 首先講...
    李欣陽閱讀 2,456評論 1 15
  • 該文章轉(zhuǎn)自:http://blog.csdn.net/evankaka/article/details/44153...
    加來依藍閱讀 7,353評論 3 87
  • 寫在前面的話: 這篇博客是我從這里“轉(zhuǎn)載”的导绷,為什么轉(zhuǎn)載兩個字加“”呢屎飘?因為這絕不是簡單的復(fù)制粘貼,我花了五六個小...
    SmartSean閱讀 4,732評論 12 45
  • 放棄其實就是一種選擇钦购。走在人生的十字路口,你必須學(xué)會放棄不適合自己的道路葵萎;面對失敗,你必須學(xué)會放棄懦弱...
    沂蒙文學(xué)閱讀 270評論 5 5