一、 進程與線程
在談論線程之前,我們先來看看什麼叫進程,以及進程與線程的關系。
進程
我們在windows操作系統中打開任務管理器,可以看到有一項是“進程”,裡面列舉出了用戶目前正在運行的所有進程,包括系統進程和用戶應用程序進程,以及每個進程所占用的內存資源等信息。進程是操作系統結構的基礎,它不僅只包括運行的程序代碼,還包括當前的活動。對於每一個進程,操作系統都會為其分配一個獨立的內存塊,各進程間資源是不共享的。
劃分時間片,宏觀上並行,微觀上串行
線程
一個Java程序運行之後,就會啟動一個JVM實例進程,這個進程就負責處理這個程序所有的操作,直到程序結束,進程也隨之結束。
而線程就是再在進程的內部將CPU資源進行再次劃分,以滿足同時處理多條語句的需要(微觀上,其實也是並行執行的),這些線程在進程內部的資源是共享的(正因如此,才會有同步以及鎖的出現)。
JVM進程啟動一定會有一個主線程存在,即main方法啟動的線程,這個線程是Java程序的入口,我們可以在main方法內部在定義我們自己的線程,這樣就可以實現多線程了。
二、 Java多線程的實現方式
java.lang.Thread類的一個對象就代表一個線程
線程是底層OS(操作系統)維護的資源,JVM跑在OS上,在JVM中創建一個Thread對象,調用其start()方法,底層OS會申請一個線程資源,線程對象可到底層管理一個線程,創建好線程之後,把要讓線程執行的代碼封裝到線程對象中(覆蓋run()方法)。
實現線程代碼的方式:
1、繼承Thread類,覆蓋run()方法
去底層申請線程並運行,對線程對象調start()方法,main方法是一個主線程
宏觀並行,微觀串行
2、實現Runnable接口
使用多態獲得Runnable對象,成為目標對象
再利用目標對象構造線程對象Thread t = new Thread(target);//target為Runnable接口類型
對於中兩種方法的具體介紹可以參考 http://www.linuxidc.com/Linux/2013-12/93690.htm
三、 線程的優先級
線程的優先級是從0-10的整數,0表示最低,5表示普通,10表示最大;JVM會自動將java線程的優先級轉換為操作系統的優先級。
main線程的優先級是5。
四、 線程的狀態
下面為線程中的7個非常重要的狀態(有的書上也只有認為前五種狀態:而將“鎖池”和“等待池”都看成是“阻塞”狀態的特殊情況:這種認識也是正確的,但是將“鎖池”和“等待池”單獨分離出來有利於對程序的理解):
1、 初始狀態:線程剛創建(Thread th = new Thread(target);)
2、 可運行狀態:線程創建之後調用它的start()方法,此時線程狀態就變更為可運行狀態,但一定就會立即運行,需要等待獲得CPU。
3、 運行狀態:調用線程的start()方法之後,線程就會進入等待運行狀態(可運行狀態),此時一旦該線程獲得CPU的使用權,縣城就會立即進入運行狀態,即執行線程的run()方法。
4、 阻塞狀態:線程失去CPU的使用權,進入一種等待狀態,注意不是可運行狀態。有以下三種情況會使線程進入阻塞狀態:
(1) 等待外部設備輸入:如等待鍵盤輸入,則該線程會進入阻塞狀態直到輸入完畢,注意:阻塞結束之後是進入可運行狀態,而不是運行狀態。
(2) 線程休眠,即調用線程的sleep()方法。Sleep()方法有一個參數,表示休眠的時間,當線程休眠的時間到達指定時間後,線程會自動結束阻塞狀態而進入可運行狀態,等待CPU。
(3) 一個線程調用另一個線程的join()方法,join()方法指的是調用該方法的線程將進入阻塞狀態直到被調用join()方法的線程運行結束之後,才會進入可運行狀態。
例:在t2線程的run()方法內部有這樣一句代碼t1.join();(t1是一個線程對象),這將意味著黨線程t2執行到該語句時就會調用線程t1的join()方法,從而t2進入阻塞狀態,直到t1運行結束為止。
5、 終止狀態:即線程執行結束
6、 鎖池狀態
7、 等待隊列
更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2013-12/93691p2.htm