Java執行緒 4 執行緒狀態的轉換

2021-07-24 02:46:18 字數 3465 閱讀 1805

執行緒的狀態轉換是執行緒控制的基礎。執行緒狀態總的可分為五大狀態:分別是生、死、可執行、執行、等待/阻塞。用乙個圖來描述如下:

1、新狀態:執行緒物件已經建立,還沒有在其上呼叫start()方法。

3、執行狀態:執行緒排程程式從可執行池中選擇乙個執行緒作為當前執行緒時執行緒所處的狀態。這也是執行緒進入執行狀態的唯一一種方式。

4、等待/阻塞/睡眠狀態:這是執行緒有資格執行時它所處的狀態。實際上這個三狀態組合為一種,其共同點是:執行緒仍舊是活的,但是當前沒有條件執行。換句話說,它是可執行的,但是如果某件事件出現,他可能返回到可執行狀態。

5、死亡態:當執行緒的run()方法完成時就認為它死去。這個執行緒物件也許是活的,但是,它已經不是乙個單獨執行的執行緒。執行緒一旦死亡,就不能復生。 如果在乙個死去的執行緒

對於執行緒的阻止,考慮一下三個方面,不考慮io阻塞的情況:

睡眠;等待;

因為需要乙個物件的鎖定而被阻塞。

1、睡眠

thread.sleep(long millis)和thread.sleep(long millis, int nanos)靜態方法強制當前正在執行的執行緒休眠(暫停執行),以「減慢執行緒」。當執行緒睡眠時,它入睡在某個地方,在甦醒之前不會返回到可執行狀態。當睡眠時間到期,則返回到可執行狀態。

睡眠的實現:呼叫靜態方法。

try

catch (interruptedexception e)

睡眠的位置:為了讓其他執行緒有機會執行,可以將thread.sleep()的呼叫放執行緒run()之內。這樣才能保證該執行緒執行過程中會睡眠。

例如,在前面的例子中,將乙個耗時的操作改為睡眠,以減慢執行緒的執行。可以這麼寫:

public

void

run() catch (interruptedexception e)

system.out.println(this.getname()+" :"+i);}}

執行結果:

阿三 :0 

李四 :0

阿三 :1

阿三 :2

阿三 :3

李四 :1

李四 :2

阿三 :4

李四 :3

李四 :4

process

finished

with

exit

code 0

這樣,執行緒在每次執行過程中,總會睡眠3毫秒,睡眠了,其他的執行緒就有機會執行了。注意:1、執行緒睡眠是幫助所有執行緒獲得執行機會的最好方法。

2、執行緒睡眠到期自動甦醒,並返回到可執行狀態,不是執行狀態。sleep()中指定的時間是執行緒不會執行的最短時間。因此,sleep()方法不能保證該執行緒睡眠到期後就開始執行。

3、sleep()是靜態方法,只能控制當前正在執行的執行緒。

執行緒的讓步是通過thread.yield()來實現的。yield()方法的作用是:暫停當前正在執行的執行緒物件,並執行其他執行緒。

要理解yield(),必須了解執行緒的優先順序的概念。執行緒總是存在優先順序,優先順序範圍在1~10之間。jvm執行緒排程程式是基於優先順序的搶先排程機制。在大多數情況下,當前執行的執行緒優先順序將大於或等於執行緒池中任何執行緒的優先順序。但這僅僅是大多數情況。

注意:當設計多執行緒應用程式的時候,一定不要依賴於執行緒的優先順序。因為執行緒排程優先順序操作是沒有保障的,只能把執行緒優先順序作用作為一種提高程式效率的方法,但是要保證程式不依賴這種操作。

當執行緒池中線程都具有相同的優先順序,排程程式的jvm實現自由選擇它喜歡的執行緒。這時候排程程式的操作有兩種可能:一是選擇乙個執行緒執行,直到它阻塞或者執行完成為止。二是時間分片,為池內的每個執行緒提供均等的執行機會。

設定執行緒的優先順序:執行緒預設的優先順序是建立它的執行執行緒的優先順序。可以通過setpriority(int newpriority)更改執行緒的優先順序。例如:

thread t = new mythread();

t.setpriority(8);

t.start();

執行緒優先順序為1~10之間的正整數,jvm從不會改變乙個執行緒的優先順序。然而,1~10之間的值是沒***的。一些jvm可能不能識別10個不同的值,而將這些優先順序進行每兩個或多個合併,變成少於10個的優先順序,則兩個或多個優先順序的執行緒可能被對映為乙個優先順序。

執行緒預設優先順序是5,thread類中有三個常量,定義執行緒優先順序範圍:

static int max_priority

執行緒可以具有的最高優先順序。

static int min_priority

執行緒可以具有的最低優先順序。

static int norm_priority

分配給執行緒的預設優先順序。

thread.yield()方法作用是:暫停當前正在執行的執行緒物件,並執行其他執行緒。

yield()應該做的是讓當前執行執行緒回到可執行狀態,以允許具有相同優先順序的其他執行緒獲得執行機會。因此,使用yield()的目的是讓相同優先順序的執行緒之間能適當的輪轉執行。但是,實際中無法保證yield()達到讓步目的,因為讓步的執行緒還有可能被執行緒排程程式再次選中。

結論:yield()從未導致執行緒轉到等待/睡眠/阻塞狀態。在大多數情況下,yield()將導致執行緒從執行狀態轉到可執行狀態,但有可能沒有效果。

thread的非靜態方法join()讓乙個執行緒(當前執行緒)b「加入」到另外乙個執行緒a的尾部。在a執行完畢之前,b不能工作。例如:

thread t =

new mythread();

t.start();

t.join();

另外,join()方法還有帶超時限制的過載版本。 例如t.join(5000);則讓執行緒等待5000毫秒,如果超過這個時間,則停止等待,變為可執行狀態。

小結 到目前位置,介紹了執行緒離開執行狀態的3種方法:

1、呼叫thread.sleep():使當前執行緒睡眠至少多少毫秒(儘管它可能在指定的時間之前被中斷)。

2、呼叫thread.yield():不能保障太多事情,儘管通常它會讓當前執行執行緒回到可執行性狀態,使得有相同優先順序的執行緒有機會執行。

3、呼叫join()方法:保證當前執行緒停止執行,直到該執行緒所加入的執行緒完成為止。然而,如果它加入的執行緒沒有存活,則當前執行緒不需要停止。

除了以上三種方式外,還有下面幾種特殊情況可能使執行緒離開執行狀態:

1、執行緒的run()方法完成。

3、執行緒不能在物件上獲得

鎖定,它正試圖執行該物件的方法**。

4、執行緒排程程式可以決定將當前執行狀態移動到可執行狀態,以便讓另乙個執行緒獲得執行機會,而不需要任何理由。

java多執行緒 執行緒狀態轉換

img 1.新建 new 新建立了乙個執行緒物件。2.可執行 runnable 執行緒物件建立後,其他執行緒 比如main執行緒 呼叫了該物件的start 方法。該狀態的執行緒位於可執行執行緒池中,等待被執行緒排程選中,獲取cpu 的使用權 3.執行 running 可執行狀態 runnable 的...

java 執行緒 執行緒的狀態及其狀態的轉換

new 新建立執行緒,初始態 runnable 可執行狀態,當前狀態的執行緒位於 可執行執行緒池 中,變得可執行,只等待獲取cpu的使用權,即當前執行緒獲得了除cpu以外的所有資源。running 正在執行。此時執行緒獲得了cpu的使用權,執行程式 blocked 阻塞狀態。執行緒因為某種原因放棄了...

Java 執行緒的狀態轉換

執行緒可以分為4個狀態 new 新生 runnable 可執行 為了方便分析,還可將其分為 runnable與running。blocked 被阻塞 dead 死亡 img 1,新生線程 2,可執行執行緒 a runnable 一旦呼叫了start方法,就進入到runnable狀態。b runnin...