認識Thread的start和run
1) start:
用 start方法來啓動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。通過調用Thread類的 start()方法來啓動一個線程,這時此線程處於就緒(可運行)狀態,並沒有運行,一旦得到cpu時間片,就開始執行run()方法,這裏方法 run()稱爲線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。2) run:
run()方法只是類的一個普通方法而已,如果直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑還是隻有一條,還是要順序執行,還是要等待run方法體執行完畢後纔可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。總結:
調用start方法方可啓動線程,而run方法只是thread的一個普通方法調用,還是在主線程裏執行。
例如:DownloadThread downloadThread = new DownloadThread(mp3Info);
//啓動新線程
Thread thread = new Thread(downloadThread);
thread.start();
線程狀態說明
線程狀態從大的方面來說,可歸結爲:初始狀態、可運行狀態、不可運行狀態和消亡狀態,具體可細分爲上圖所示7個狀態,說明如下:1) 線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable接口,但不管怎樣,當我們new了thread實例後,線程就進入了初始狀態;
2) 當該對象調用了start()方法,就進入可運行狀態;
3) 進入可運行狀態後,當該對象被操作系統選中,獲得CPU時間片就會進入運行狀態;
4) 進入運行狀態後case就比較多,大致有如下情形:
- run()方法或main()方法結束後,線程就進入終止狀態;
- 當線程調用了自身的sleep()方法或其他線程的join()方法,就會進入阻塞狀態(該狀態既停止當前線程,但並不釋放所佔有的資源)。當 sleep()結束或join()結束後,該線程進入可運行狀態,繼續等待OS分配時間片;
- 當線程剛進入可運行狀態(注意,還沒運行),發現將要調用的資源被鎖牢(synchroniza,lock),將會立即進入鎖池狀態,等待獲取鎖標記(這 時的鎖池裏也許已經有了其他線程在等待獲取鎖標記,這時它們處於隊列狀態,既先到先得),一旦線程獲得鎖標記後,就轉入可運行狀態,等待OS分配 CPU時間片;
- 當線程調用wait()方法後會進入等待隊列(進入這個狀態會釋放所佔有的所有資源,與阻塞狀態不同),進入這個狀態後,是不能自動喚醒的,必須依靠其他 線程調用notify()或notifyAll()方法才能被喚醒(由於notify()只是喚醒一個線程,但我們由不能確定具體喚醒的是哪一個線程,也 許我們需要喚醒的線程不能夠被喚醒,因此在實際使用時,一般都用notifyAll()方法,喚醒有所線程),線程被喚醒後會進入鎖池,等待獲取鎖標記。
- 當線程調用stop方法,即可使線程進入消亡狀態,但是由於stop方法是不安全的,不鼓勵使用,大家可以通過run方法裏的條件變通實現線程的 stop。