java線程狀態轉換
㈠ 簡速java語言中線程對象都有哪些狀態,這些狀態如何變化
線程的狀態轉換是線程式控制制的基礎。線程狀態總的可分為五大狀態:分別是生、死、可運行、運行、等待/阻塞。用一個圖來描述如下:
1、新狀態:線程對象已經創建,還沒有在其上調用start()方法。
2、可運行狀態:當線程有資格運行,但調度程序還沒有把它選定為運行線程時線程所處的狀態。當start()方法調用時,線程首先進入可運行狀態。在線程運行之後或者從阻塞、等待或睡眠狀態回來後,也返回到可運行狀態。
3、運行狀態:線程調度程序從可運行池中選擇一個線程作為當前線程時線程所處的狀態。這也是線程進入運行狀態的唯一一種方式。
4、等待/阻塞/睡眠狀態:這是線程有資格運行時它所處的狀態。實際上這個三狀態組合為一種,其共同點是:線程仍舊是活的,但是當前沒有條件運行。換句話說,它是可運行的,但是如果某件事件出現,他可能返回到可運行狀態。
5、死亡態:當線程的run()方法完成時就認為它死去。這個線程對象也許是活的,但是,它已經不是一個單獨執行的線程。線程一旦死亡,就不能復生。 如果在一個死去的線程上調用start()方法,會拋出java.lang.IllegalThreadStateException異常。
有關詳細狀態轉換圖可以參看本人的「Java多線程編程總結」中的圖
二、阻止線程執行
對於線程的阻止,考慮一下三個方面,不考慮IO阻塞的情況:
睡眠;
等待;
因為需要一個對象的鎖定而被阻塞。
1、睡眠
Thread.sleep(long millis)和Thread.sleep(long millis, int nanos)靜態方法強制當前正在執行的線程休眠(暫停執行),以「減慢線程」。當線程睡眠時,它入睡在某個地方,在蘇醒之前不會返回到可運行狀態。當睡眠時間到期,則返回到可運行狀態。
線程睡眠的原因:線程執行太快,或者需要強制進入下一輪,因為Java規范不保證合理的輪換。
睡眠的實現:調用靜態方法。
try {
Thread.sleep(123);
} catch (InterruptedException e) {
e.printStackTrace();
}
睡眠的位置:為了讓其他線程有機會執行,可以將Thread.sleep()的調用放線程run()之內。這樣才能保證該線程執行過程中會睡眠。
例如,在前面的例子中,將一個耗時的操作改為睡眠,以減慢線程的執行。可以這么寫:
public void run() {
for(int i = 0;i<5;i++){
// 很耗時的操作,用來減慢線程的執行
// for(long k= 0; k <100000000;k++);
try {
Thread.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace(); .
}
System.out.println(this.getName()+" :"+i);
}
}
㈡ java線程中的幾種狀態以及相互轉換
NEW:線程創建之後,但是還沒有啟動(notyetstarted)。
RUNNABLE:正在Java虛擬機下跑任務的線程的狀態。在RUNNABLE狀態下的線程可能會處於等待狀態,因為它正在等待一些系統資源的釋放,比如IO
BLOCKED:阻塞狀態,等待鎖的釋放,比如線程A進入了一個synchronized方法,線程B也想進入這個方法,但是這個方法的鎖已經被線程A獲取了,這個時候線程B就處於BLOCKED狀態
WAITING:等待狀態,處於等待狀態的線程是由於執行了3個方法中的任意方法。1.Object的wait方法,並且沒有使用timeout參數;2.Thread的join方法,沒有使用timeout參數3.LockSupport的park方法。處於waiting狀態的線程會等待另外一個線程處理特殊的行為。再舉個例子,如果一個線程調用了一個對象的wait方法,那麼這個線程就會處於waiting狀態直到另外一個線程調用這個對象的notify或者notifyAll方法後才會解除這個狀態
TIMED_WAITING:有等待時間的等待狀態,比如調用了以下幾個方法中的任意方法,並且指定了等待時間,線程就會處於這個狀態。1.Thread.sleep方法2.Object的wait方法,帶有時間3.Thread.join方法,帶有時間4.LockSupport的parkNanos方法,帶有時間5.LockSupport的parkUntil方法,帶有時間
TERMINATED:線程中止的狀態,這個線程已經完整地執行了它的任務
㈢ java多線程有哪些狀態,主要流轉流程
有三種:
(1)繼承Thread類,重寫run函數
創建:
class
xx
extends
Thread{
public
void
run(){
Thread.sleep(1000)
//線程休眠1000毫秒,sleep使線程進入Block狀態,並釋放資源
}}
開啟線程:
對象.start()
//啟動線程,run函數運行
(2)實現Runnable介面,重寫run函數
開啟線程:
Thread
t
=
new
Thread(對象)
//創建線程對象
t.start()
(3)實現Callable介面,重寫call函數
Callable是類似於Runnable的介面,實現Callable介面的類和實現Runnable的類都是可被其它線程執行的任務。
Callable和Runnable有幾點不同:
①Callable規定的方法是call(),而Runnable規定的方法是run().
②Callable的任務執行後可返回值,而Runnable的任務是不能返回值的
③call()方法可拋出異常,而run()方法是不能拋出異常的。
④運行Callable任務可拿到一個Future對象,Future表示非同步計算的結果。它提供了檢查計算是否完成的方法,以等
待計算的完成,並檢索計算的結果.通過Future對象可了解任務執行情況,可取消任務的執行,還可獲取任務執行的結果
㈣ Java中線程的幾種可用狀態有哪些請大家解釋一下。
線程在執行過程中,可以處於下面幾種狀態:
1、就緒(Runnable):線程准備運行,不一定立馬就能開始執行。
2、運行中(Running):進程正在執行線程的代碼。
3、等待中(Waiting):線程處於阻塞的狀態,等待外部的處理結束。
4、睡眠中(Sleeping):線程被強制睡眠。
5、I/O阻塞(BlockedonI/O):等待I/O操作完成。
6、同步阻塞(BlockedonSynchronization):等待獲取鎖。
7、死亡(Dead):線程完成了執行。
㈤ java 總結幾種線程非同步轉同步的方法
以Java語言為例:
用synchronized關鍵字修飾同步方法。
同步有幾種實現方法分別是synchronized,wait與notify
wait():使一個線程處於等待狀態,並且釋放所持有的對象的lock。
sleep():使一個正在運行的線程處於睡眠狀態,是一個靜態方法,調用此方法要捕捉InterruptedException異常。
notify():喚醒一個處於等待狀態的線程,注意的是在調用此方法的時候,並不能確切的喚醒某一個等待狀態的線程,而是由JVM確定喚醒哪個線程,而且不是按優先順序。
Allnotity():喚醒所有處入等待狀態的線程,注意並不是給所有喚醒線程一個對象的鎖,而是讓它們競爭。
同步是多線程中的重要概念。同步的使用可以保證在多線程運行的環境中,程序不會產生設計之外的錯誤結果。同步的實現方式有兩種,同步方法和同步塊,這兩種方式都要用到synchronized關鍵字。
給一個方法增加synchronized修飾符之後就可以使它成為同步方法,這個方法可以是靜態方法和非靜態方法,但是不能是抽象類的抽象方法,也不能是介面中的介面方法。下面代碼是一個同步方法的示例:
public synchronized void aMethod() {
// do something
}
public static synchronized void anotherMethod() {
// do something
}
線程在執行同步方法時是具有排它性的。當任意一個線程進入到一個對象的任意一個同步方法時,這個對象的所有同步方法都被鎖定了,在此期間,其他任何線程都不能訪問這個對象的任意一個同步方法,直到這個線程執行完它所調用的同步方法並從中退出,從而導致它釋放了該對象的同步鎖之後。在一個對象被某個線程鎖定之後,其他線程是可以訪問這個對象的所有非同步方法的。
同步塊是通過鎖定一個指定的對象,來對同步塊中包含的代碼進行同步;而同步方法是對這個方法塊里的代碼進行同步,而這種情況下鎖定的對象就是同步方法所屬的主體對象自身。如果這個方法是靜態同步方法呢?那麼線程鎖定的就不是這個類的對象了,也不是這個類自身,而是這個類對應的java.lang.Class類型的對象。同步方法和同步塊之間的相互制約只限於同一個對象之間,所以靜態同步方法只受它所屬類的其它靜態同步方法的制約,而跟這個類的實例(對象)沒有關系。
㈥ JAVA語言中請寫出線程從阻塞狀態恢復到就緒狀態的三種途徑
線程從阻塞狀態恢復到就緒狀態,有三種途徑:自動恢復、用resume()方法恢復,notify方法恢復。
當編輯並運行一個Java程序時,需要同時涉及到這四種方面。使用文字編輯軟體或集成開發環境在Java源文件中定義不同的類 ,通過調用類中的方法來訪問資源系統。
把源文件編譯生成一種二進制中間碼,存儲在class文件中,然後再通過運行與操作系統平台環境相對應的Java虛擬機來運行class文件,執行編譯產生的位元組碼,調用class文件中實現的方法來滿足程序的Java API調用。
(6)java線程狀態轉換擴展閱讀:
整數型用來存儲整數數值,即沒有小數部分的數值。可以是正數,也可以是負數。整數數據在Java程序中有3種表示形式,分別為十進制、八進制和十六進制。
自增和自減是單目運算符,可以放在操作元之前,也可以放在操作元之後。操作元必須是一個整型或浮點型變數。自增、自減運算符的作用是使變數的值增1或減1。
放在操作元前面的自增、自減運算符,會先將變數的值加1或減1,然後再使該變數參與表達式的運算。放在操作元後面的自增、自減運算符,會先使變數參與表達式的運算,然後再將該變數的值加1或減1。
㈦ java線程的幾種轉態
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
㈧ JAVA中,線程有哪五個基本狀態他們之間如何讓轉化並簡述線程周期。
java中,每個線程都需經歷新生、就緒、運行、阻塞和死亡五種狀態,線程從新生到死亡的狀態變化稱為生命周期。
用new運算符和Thread類或其子類建立一個線程對象後,該線程就處於新生狀態。
㈨ JAVA中線程有哪五個基本狀態它們之間如何讓轉化
java中,每個線程都需經歷新生、就緒、運行、阻塞和死亡五種狀態,線程從新生到死亡的狀態變化稱為生命周期。
用new運算符和Thread類或其子類建立一個線程對象後,該線程就處於新生狀態。
新生--->就緒:通過調用start()方法
就緒--->運行:處於就緒狀態的線程一旦得到CPU,就進入運行狀態並自動調用自己的run()方法
運行--->阻塞:處於運行狀態的線程,執行sleep()方法,或等待I/O設備資源,讓出CPU並暫時中止自己運行,進入阻塞狀態
阻塞--->就緒:睡眠時間已到,或等待的I/O設備空閑下來,線程便進入就緒狀態,重新到就緒隊列中等待CPU。當再次獲得CPU時,便從原來中止位置開始繼續運行。
運行--->死亡:(1)(正常情況下)線程任務完成
(2)(非正常狀況)線程被強制性的中止,如通過執行stop()或destroy()方法來終止一個線程
㈩ Java線程的幾種狀態
線程是一個動態執行的過程,它有一個從產生到死亡的過程,共五種狀態:
1、新建(new Thread)
當創建Thread類的一個實例(對象)時,此線程進入新建狀態(未被啟動)
例如:Thread t1=new Thread();
2、就緒(runnable)
線程已經被啟動,正在等待被分配給CPU時間片,也就是說此時線程正在就緒隊列中排隊等候得到CPU資源。例如:t1.start();
3、運行(running)
線程獲得CPU資源正在執行任務(run()方法),此時除非此線程自動放棄CPU資源或者有優先順序更高的線程進入,線程將一直運行到結束。
4、堵塞(blocked)
由於某種原因導致正在運行的線程讓出CPU並暫停自己的執行,即進入堵塞狀態。
正在睡眠:用sleep(long t) 方法可使線程進入睡眠方式。一個睡眠著的線程在指定的時間過去可進入就緒狀態。
正在等待:調用wait()方法。(調用notify()方法回到就緒狀態)
被另一個線程所阻塞:調用suspend()方法。(調用resume()方法恢復)
5、死亡(dead)
當線程執行完畢或被其它線程殺死,線程就進入死亡狀態,這時線程不可能再進入就緒狀態等待執行。
自然終止:正常運行run()方法後終止
異常終止:調用stop()方法讓一個線程終止運行