Java中 實現多線程有兩種途徑:繼承Thread類或者實現Runnable接口。Runnable是接口,建議用接口的方式生成線程,由於接口能夠實現多繼承, 何況Runnable只有一個run方法,很適合繼承。在使用Thread的時候只需繼承Thread,而且new一個實例出來,調用 start()方法便可以啓動一個線程。java
Thread Test = new Thread(); Test.start();
在使用Runnable的時候須要先new一個實現Runnable的實例,以後啓動Thread便可。編程
Test impelements Runnable; Test t = new Test(); Thread test = new Thread(t); test.start();
總結:Thread和Runnable是實現java多線程的2種方式,runable是接口,thread是類,建議使用runable實現 java多線程,無論如何,最終都須要經過thread.start()來使線程處於可運行狀態。api
1) start:用 start方法來啓動線程,真正實現了多線程運行,這時無需等待run方法體代碼執行完畢而直接繼續執行下面的代碼。經過調用Thread類的 start()方法來啓動一個線程,這時此線程處於就緒(可運行)狀態,並無運行,一旦獲得cpu時間片,就開始執行run()方法,這裏方法 run()稱爲線程體,它包含了要執行的這個線程的內容,Run方法運行結束,此線程隨即終止。安全
2) run:run()方法只是類的一個普通方法而已,若是直接調用Run方法,程序中依然只有主線程這一個線程,其程序執行路徑仍是隻有一條,仍是要順序執行,仍是要等待run方法體執行完畢後纔可繼續執行下面的代碼,這樣就沒有達到寫線程的目的。多線程
總結:調用start方法方可啓動線程,而run方法只是thread的一個普通方法調用,仍是在主線程裏執行。函數
線程狀態從大的方面來講,可歸結爲:初始狀態、可運行狀態、不可運行狀態和消亡狀態,具體可細分爲7個狀態,說明以下:工具
1) 線程的實現有兩種方式,一是繼承Thread類,二是實現Runnable接口,但無論怎樣,當咱們new了thread實例後,線程就進入了初始狀態;spa
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。
Timer 是一種定時器工具,用來在一個後臺線程計劃執行指定任務,這些任務能夠被執行一次,也能夠被按期執行。每一個 Timer 對象對應一個後 臺線程,順序地執行全部計時器任務。若是完成某個計時器任務的時間太長,那麼它會「獨佔」計時器的任務執行線程,從而可能延遲後續任務的執行。對 Timer 對象最後的引用完成而且全部未處理的任務都已執行完成後,計時器的任務執行線程會正常終止(而且成爲垃圾回收的對象)。TimerTask是一個抽象類, 實現了Runable接口,它的子類表明一個能夠被Timer計劃的任務。
1) 一個簡單的Demo,讓你們對Timer、TimerTask的使用有感性的認識。
2) Timer和TimerTask的經常使用api函數說明
這裏強調Timer 類的schedule和scheduleAtFixedRate的區別。schedule和 scheduleAtFixedRate的區別在於,schedule以固定的相對時間間隔執行,若是某一次執行被延時了,日後的執行的執行時間也會相對 延時;而scheduleAtFixedRate是以絕對的時間間隔執行,若是某一次執行被延時,它的後一次執行的延時將會縮短 (scheduleAtFixedRate會把已通過去的時間也做爲週期執行)。schedule注重的是時間間隔的穩定,而 scheduleAtFixedRate注重的是執行頻率的穩定。
3) Timer的終止
默認狀況下,只要一個程序的timer線程在運行,那麼這個程序就會保持運行。固然,你能夠經過如下四種方法終止一個timer線程:
a)調用timer的cancle方法。你能夠從程序的任何地方調用此方法,甚至在一個timer task的run方法裏;
b)讓timer線程成爲一個daemon線程(能夠在建立timer時使用new Timer(true)達到這個目地),這樣當程序只有daemon線程的時候,它就會自動終止運行;
c)當timer相關的全部task執行完畢之後,刪除全部此timer對象的引用(置成null),這樣timer線程也會終止;
d)調用System.exit方法,使整個程序(全部線程)終止。
總結:Timer 和TimerTask能夠簡單理解爲Timer定時器在觸發TimerTask任務調用,一般用schedule和 scheduleAtFixedRate方法來調用timertask任務,cancle來終止任務調用。Timer簡單易用,比較適合提供輕量級的計時 器功能,可是對時效性很強的任務調度請用其它方法來實現(正如javadoc所述」Timer does not offer real-time guarantees: it schedules tasks using the Object.wait(long) method」)。
文章轉載自:樂橙谷公會 http://www.lechenggu.com/bbs/topic/57ecce7c13c3986107ad92de