多線(xiàn)程的系列前面已經(jīng)寫(xiě)了很多了,有興趣的可以去我的倉(cāng)庫(kù)康康,,今天呢?我也是看到人家寫(xiě)的不錯(cuò),,然后自己隨便抄襲下,,哈哈,其實(shí)就是把看到的知識(shí)記錄一下下,。自己寫(xiě)一遍的話(huà),,可能記憶深刻一點(diǎn)。 線(xiàn)程狀態(tài)轉(zhuǎn)換圖
注意: 調(diào)用obj.wait()的線(xiàn)程需要先獲取obj的monitor,,wait()會(huì)釋放obj的monitor并進(jìn)入等待態(tài),。所以wait()/notify()都要與synchronized聯(lián)用。 阻塞與等待的區(qū)別阻塞:當(dāng)一個(gè)線(xiàn)程試圖獲取對(duì)象鎖(非java.util.concurrent庫(kù)中的鎖,,即synchronized),,而該鎖被其他線(xiàn)程持有,則該線(xiàn)程進(jìn)入阻塞狀態(tài)。它的特點(diǎn)是使用簡(jiǎn)單,,由JVM調(diào)度器來(lái)決定喚醒自己,,而不需要由另一個(gè)線(xiàn)程來(lái)顯式喚醒自己,不響應(yīng)中斷,。 阻塞 一個(gè)線(xiàn)程因?yàn)榈却R界區(qū)的鎖被阻塞產(chǎn)生的狀態(tài) 等待:當(dāng)一個(gè)線(xiàn)程等待另一個(gè)線(xiàn)程通知調(diào)度器一個(gè)條件時(shí),,該線(xiàn)程進(jìn)入等待狀態(tài)。它的特點(diǎn)是需要等待另一個(gè)線(xiàn)程顯式地喚醒自己,,實(shí)現(xiàn)靈活,,語(yǔ)義更豐富,可響應(yīng)中斷,。例如調(diào)用:Object.wait(),、Thread.join()以及等待Lock或Condition。 等待 一個(gè)線(xiàn)程進(jìn)入了鎖,,但是需要等待其他線(xiàn)程執(zhí)行某些操作 需要強(qiáng)調(diào)的是雖然synchronized和JUC里的Lock都實(shí)現(xiàn)鎖的功能,,但線(xiàn)程進(jìn)入的狀態(tài)是不一樣的。synchronized會(huì)讓線(xiàn)程進(jìn)入阻塞態(tài),,而JUC里的Lock是用LockSupport.park()/unpark()來(lái)實(shí)現(xiàn)阻塞/喚醒的,,會(huì)讓線(xiàn)程進(jìn)入等待態(tài)。但話(huà)又說(shuō)回來(lái),,雖然等鎖時(shí)進(jìn)入的狀態(tài)不一樣,,但被喚醒后又都進(jìn)入runnable態(tài),從行為效果來(lái)看又是一樣的,。 一個(gè)線(xiàn)程進(jìn)入了鎖,,但是需要等待其他線(xiàn)程執(zhí)行某些操作 主要操作start()新啟一個(gè)線(xiàn)程執(zhí)行其run()方法,一個(gè)線(xiàn)程只能start一次,。主要是通過(guò)調(diào)用native start0()來(lái)實(shí)現(xiàn),。 public synchronized void start() {?????//判斷是否首次啟動(dòng) if (threadStatus != 0) throw new IllegalThreadStateException(); group.add(this); boolean started = false; try {???????//啟動(dòng)線(xiàn)程 start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } private native void start0();復(fù)制代碼 run()run()方法是不需要用戶(hù)來(lái)調(diào)用的,當(dāng)通過(guò)start方法啟動(dòng)一個(gè)線(xiàn)程之后,,當(dāng)該線(xiàn)程獲得了CPU執(zhí)行時(shí)間,,便進(jìn)入run方法體去執(zhí)行具體的任務(wù)。注意,,繼承Thread類(lèi)必須重寫(xiě)run方法,,在run方法中定義具體要執(zhí)行的任務(wù)。 sleep()sleep方法有兩個(gè)重載版本
sleep相當(dāng)于讓線(xiàn)程睡眠,,交出CPU,讓CPU去執(zhí)行其他的任務(wù),。 但是有一點(diǎn)要非常注意,,sleep方法不會(huì)釋放鎖,,也就是說(shuō)如果當(dāng)前線(xiàn)程持有對(duì)某個(gè)對(duì)象的鎖,則即使調(diào)用sleep方法,,其他線(xiàn)程也無(wú)法訪(fǎng)問(wèn)這個(gè)對(duì)象,。 yield()調(diào)用yield方法會(huì)讓當(dāng)前線(xiàn)程交出CPU權(quán)限,讓CPU去執(zhí)行其他的線(xiàn)程,。它跟sleep方法類(lèi)似,,同樣不會(huì)釋放鎖。但是yield不能控制具體的交出CPU的時(shí)間,,另外,,yield方法只能讓擁有相同優(yōu)先級(jí)的線(xiàn)程有獲取CPU執(zhí)行時(shí)間的機(jī)會(huì)。 注意,,調(diào)用yield方法并不會(huì)讓線(xiàn)程進(jìn)入阻塞狀態(tài),,而是讓線(xiàn)程重回就緒狀態(tài),它只需要等待重新獲取CPU執(zhí)行時(shí)間,,這一點(diǎn)是和sleep方法不一樣的,。 join()join方法有三個(gè)重載版本 1 join()2 join(long millis) //參數(shù)為毫秒3 join(long millis,int nanoseconds) //第一參數(shù)為毫秒,第二個(gè)參數(shù)為納秒 join()實(shí)際是利用了wait(),,只不過(guò)它不用等待notify()/notifyAll(),,且不受其影響。它結(jié)束的條件是:1)等待時(shí)間到,;2)目標(biāo)線(xiàn)程已經(jīng)run完(通過(guò)isAlive()來(lái)判斷),。
interrupt()此操作會(huì)將線(xiàn)程的中斷標(biāo)志位置位,,至于線(xiàn)程作何動(dòng)作那要看線(xiàn)程了。
可以通過(guò)以下三種方式來(lái)判斷中斷:
|
|
來(lái)自: 吳敬銳 > 《待分類(lèi)》