
先從圖片開始
小小的作下解釋:
1、線程的實(shí)現(xiàn)有兩種方式,一是繼承Thread類,二是實(shí)現(xiàn)Runnable接口,但不管怎樣,當(dāng)我們new了這個對象后,線程就進(jìn)入了初始狀態(tài);
2、當(dāng)該對象調(diào)用了start()方法,就進(jìn)入可運(yùn)行狀態(tài);
3、進(jìn)入可運(yùn)行狀態(tài)后,當(dāng)該對象被操作系統(tǒng)選中,獲得CPU時間片就會進(jìn)入運(yùn)行狀態(tài);
4、進(jìn)入運(yùn)行狀態(tài)后情況就比較復(fù)雜了
4.1 run()方法或main()方法結(jié)束后,線程就進(jìn)入終止?fàn)顟B(tài);
4.2 當(dāng)線程調(diào)用了自身的sleep()方法或其他線程的join()方法,就會進(jìn)入阻塞狀態(tài)(該狀態(tài)既停止當(dāng)前線程,但并不釋放所占有的資源)。當(dāng)sleep()結(jié)束或join()結(jié)束后,該線程進(jìn)入可運(yùn)行狀態(tài),繼續(xù)等待OS分配時間片;
4.3 線程調(diào)用了yield()方法,意思是放棄當(dāng)前獲得的CPU時間片,回到可運(yùn)行狀態(tài),這時與其他進(jìn)程處于同等競爭狀態(tài),OS有可能會接著又讓這個進(jìn)程進(jìn)入運(yùn)行狀態(tài);
4.4 當(dāng)線程剛進(jìn)入可運(yùn)行狀態(tài)(注意,還沒運(yùn)行),發(fā)現(xiàn)將要調(diào)用的資源被synchroniza(同步),獲取不到鎖標(biāo)記,將會立即進(jìn)入鎖池 狀態(tài),等待獲取鎖標(biāo)記(這時的鎖池里也許已經(jīng)有了其他線程在等待獲取鎖標(biāo)記,這時它們處于隊列狀態(tài),既先到先得),一旦線程獲得鎖標(biāo)記后,就轉(zhuǎn)入可運(yùn)行狀態(tài),等待OS分配CPU時間片;
4.5 當(dāng)線程調(diào)用wait()方法后會進(jìn)入等待隊列(進(jìn)入這個狀態(tài)會釋放所占有的所有資源,與阻塞狀態(tài)不同),進(jìn)入這個狀態(tài)后,是不能自動喚 醒的,必須依靠其他線程調(diào)用notify()或notifyAll()方法才能被喚醒(由于notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也許我們需要喚醒的線程不能夠被喚醒,因此在實(shí)際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒后會進(jìn)入鎖 池,等待獲取鎖標(biāo)記。
總算全部回憶了一遍JDK1.5在API的使用上有了較好的改進(jìn),效率得到很大的提高,不過幾個狀態(tài)轉(zhuǎn)換的原理還是一樣。