引言?? 區(qū)分清楚進程和線程
1、操作系統(tǒng)有兩個容易混淆的概念,進程和線程。
進程:一個計算機程序的運行實例,包含了需要執(zhí)行的指令;有自己的獨立地址空間,包含程序內(nèi)容和數(shù)據(jù);不同進程的地址空間是互相隔離的;進程擁有各種資源和狀態(tài)信息,包括打開的文件、子進程和信號處理。
線程:表示程序的執(zhí)行流程,是CPU調(diào)度執(zhí)行的基本單位;線程有自己的程序計數(shù)器、寄存器、堆棧和幀。同一進程中的線程共用相同的地址空間,同時共享進進程鎖擁有的內(nèi)存和其他資源。
2、Java標準庫提供了進程和線程相關(guān)的API,進程主要包括表示進程的java.lang.Process類和創(chuàng)建進程的java.lang.ProcessBuilder類;????? 表示線程的是java.lang.Thread類,在虛擬機啟動之后,通常只有Java類的main方法這個普通線程運行,運行時可以創(chuàng)建和啟動新的線程;還有一類守護線程(damonthread),守護線程在后臺運行,提供程序運行時所需的服務(wù)。當虛擬機中運行的所有線程都是守護線程時,虛擬機終止運行。
一、線程的生命周期及五種基本狀態(tài)
新建狀態(tài)(New):當線程對象對創(chuàng)建后,即進入了新建狀態(tài),如:Thread t = new MyThread();
就緒狀態(tài)(Runnable):當調(diào)用線程對象的start()方法(t.start();),線程即進入就緒狀態(tài)。處于就緒狀態(tài)的線程,只是說明此線程已經(jīng)做好了準備,隨時等待CPU調(diào)度執(zhí)行,并不是說執(zhí)行了t.start()此線程立即就會執(zhí)行;
運行狀態(tài)(Running):當CPU開始調(diào)度處于就緒狀態(tài)的線程時,此時線程才得以真正執(zhí)行,即進入到運行狀態(tài)。注:就 ? ? 緒狀態(tài)是進入到運行狀態(tài)的唯一入口,也就是說,線程要想進入運行狀態(tài)執(zhí)行,首先必須處于就緒狀態(tài)中;
阻塞狀態(tài)(Blocked):處于運行狀態(tài)中的線程由于某種原因,暫時放棄對CPU的使用權(quán),停止執(zhí)行,此時進入阻塞狀態(tài),直到其進入到就緒狀態(tài),才 有機會再次被CPU調(diào)用以進入到運行狀態(tài)。根據(jù)阻塞產(chǎn)生的原因不同,阻塞狀態(tài)又可以分為三種:
1.等待阻塞:運行狀態(tài)中的線程執(zhí)行wait()方法,使本線程進入到等待阻塞狀態(tài);
2.同步阻塞 -- 線程在獲取synchronized同步鎖失敗(因為鎖被其它線程所占用),它會進入同步阻塞狀態(tài);
3.其他阻塞 -- 通過調(diào)用線程的sleep()或join()或發(fā)出了I/O請求時,線程會進入到阻塞狀態(tài)。當sleep()狀態(tài)超時、join()等待線程終止或者超時、或者I/O處理完畢時,線程重新轉(zhuǎn)入就緒狀態(tài)。
死亡狀態(tài)(Dead):線程執(zhí)行完了或者因異常退出了run()方法,該線程結(jié)束生命周期。
二、Java多線程的創(chuàng)建及啟動
1.繼承Thread類,重寫該類的run()方法。
2.實現(xiàn)Runnable接口,并重寫該接口的run()方法,該run()方法同樣是線程執(zhí)行體,創(chuàng)建Runnable實現(xiàn)類的實例,并以此實例作為Thread類的target來創(chuàng)建Thread對象,該Thread對象才是真正的線程對象
三、終止線程的三種方法
1.? 使用退出標志,使線程正常退出,也就是當run方法完成后線程終止。
2.使用stop方法強行終止線程(這個方法不推薦使用,因為stop和suspend、resume一樣,也可能發(fā)生不可預(yù)料的結(jié)果)。
3.使用interrupt方法中斷線程。
四、線程同步
1、synchronized關(guān)鍵字的作用域有二種:
1)是某個對象實例內(nèi),synchronized a Method(){}可以防止多個線程同時訪問這個對象的synchronized方法(如果一個對象有多個synchronized方法,只要一個線程訪問了其中的一個synchronized方法,其它線程不能同時訪問這個對象中任何一個synchronized方法)。這時,不同的對象實例的synchronized方法是不相干擾的。也就是說,其它線程照樣可以同時訪問相同類的另一個對象實例中的synchronized方法;
2)是某個類的范圍,synchronized static aStaticMethod{}防止多個線程同時訪問這個類中的synchronized static 方法。它可以對類的所有對象實例起作用。
2、除了方法前用synchronized關(guān)鍵字,synchronized關(guān)鍵字還可以用于方法中的某個區(qū)塊中,表示只對這個區(qū)塊的資源實行互斥訪問。用法是: synchronized(this){/*區(qū)塊*/},它的作用域是當前對象;
3、synchronized關(guān)鍵字是不能繼承的,也就是說,基類的方法synchronized f(){} 在繼承類中并不自動是synchronized f(){},而是變成了f(){}。繼承類需要你顯式的指定它的某個方法為synchronized方法;