Java多線程編程
這裡要先回憶一下進程,即運行中的程式,多任務作業系統中並發的一個任務(CPU是分時間片執行多個進程的),線程,其本質是進程中順序的執行流程,進程有獨立的進程空間進程中的資料存放空間(對空間和棧空間)是獨立的。線程沒有獨立的存放資料的空間,他們的資料存放區空間(堆空間)是共用的,線程間的棧空間是獨立的,線程消耗的資源也比進程小。
線程,是進程(運行中的程式)中順序的執行流程,進程可以劃分出多個線程。
JVM(java虛擬機器)本身就是一個進程,java只能夠申請建立線程。
作業系統決定線程是否有優先順序,獨佔式的作業系統中系統會有優先順序的概念,共用式的作業系統則不會優先順序的。
Java中的線程也是對象,線程類是Thread類,線程是作業系統建立並進行維護的資源,線程對象只能表示一個線程,他本身不是線程。只能通過線程對象來申請建立,中止線程,訪問底層的線程資源。
線程包含了三部分,cpu資源,代碼,資料存放區空間。
線程對象調用start()方法,線程對象就會向作業系統申請線程啟動,除了申請的線程,還有main方法的線程,也就是主線程。
注意:只有運行狀態的線程才有機會執行代碼,主線程的中止不會影響其他的正在運行中的線程,主線程中止也就是main()方法退出了,只有進程中的所有線程都中止時,進程(JVM進程)才會退出,只要有線程沒有中止,進程就不會退出。
線程編程的兩種方法
1,寫一個類,繼承Thread類,覆蓋Thread類中繼承來的run()方法,這樣就寫好了自訂的線程類。
2,寫一個類,實現Runable介面,實現其中的run()方法。這種方法寫好的類的對象需要作為線程類建立對象時構造方法的參數。
實現形式1:
Thread t=new a();
class a extends Thread{
public void run(){
//...
}
}
實現形式2:
Runable r=new b();//目標對象
Thread t=new Thread(r);//用目標物件建構線程對象
class b implements Runable{
public void run(){
//...
}
}
Thread的方法
public static void sleep(long millis) throws InterruptedException
括弧中以毫秒為單位, 使線程停止一段時間,間隔期滿後,線程不一定立即恢複執行.
當main()運行完畢,即使在結束時時間片還沒有用完,CPU也放棄此時間片,繼續運行其他程式。
Try{
Thread.sleep(1000);
}catch ( InterruptedException e){
e.printStackTrace(e);
}
public final void join() throws InterruptedException
表示其他運行線程放棄執行權,進入阻塞狀態,直到調用線程結束。
實際上是把並發的線程變為串列運行。
線程的優先順序:1-10,越大優先順序越高,優先順序越高被OS選中的可能性就越大。(不建議使用,因為不同作業系統的優先順序並不相同,使得程式不具備跨平台性,這種優先順序只是粗略地劃分)。
public static void field()
使當前線程馬上交出執行權,回到可運行狀態,等待OS的再次調用。
Public final Boolean isActive()
驗證當前線程是否是活動的,不管它是否正在運行。
線程的生命週期
下面為線程中的7種非常重要的狀態:(有的書上也只有認為前五種狀態:而將“鎖池”和“等待池”都看成是“阻塞”狀態的特殊情況:這種認識也是正確的,但是將“鎖池”和“等待池”單獨分離出來有利於對程式的理解)
1,初始狀態,線程建立,線程對象調用start()方法。
2,可運行狀態,也就是等待Cpu資源,等待啟動並執行狀態。
3,運行狀態,獲得了cpu資源,執行狀態。
4,阻塞狀態,也就是讓出cpu資源,進入一種等待狀態,而且不是可運行狀態,有三種情況會進入阻塞狀態。
1)如等待輸入(輸入裝置進行處理,而CPU不處理),則放入阻塞,直到輸入完畢,阻塞結束後會進入可運行狀態。
2)線程休眠,線程對象調用sleep()方法,阻塞結束後會進入可運行狀態。
3)線程對象2調用線程對象1的join()方法,那麼線程對象2進入阻塞狀態,直到線程對象1中止。
5,中止狀態,也就是執行結束。
6,鎖池狀態
7,等待隊列