demo:
當執行緒被建立並啟動以後,它既不是一啟動就進入了執行狀態,也不是一直處於執行狀態。
我們不需要去研究這幾種狀態的實現原理,我們只需知道在做執行緒操作中存在這樣的狀態。那我們怎麼去理解這幾個狀態呢,新建與被終止還是很容易理解的,我們就研究一下執行緒從runnable(可執行)狀態與非執行狀態之間的轉換問題。
提前了解 - sleep和wait的區別
對於 sleep()方法,我們首先要知道該方法是屬於 thread 類中的。而 wait()方法,則是屬於object 類中的。
sleep()方法導致了程式暫停執行指定的時間,讓出 cpu 該其他執行緒,但是他的監控狀態依然保持者,當指定的時間到了又會自動恢復執行狀態。
在呼叫sleep()方法的過程中,執行緒不會釋放物件鎖。
而當呼叫wait()方法的時候,執行緒會放棄物件鎖,進入等待此物件的等待鎖定池,只有針對此物件呼叫 notify()方法後本執行緒才進入物件鎖定池準備獲取物件鎖進入執行狀態。
timed waiting在api中的描述為:乙個正在限時等待另乙個執行緒執行乙個(喚醒)動作的執行緒處於這一狀態。單獨的去理解這句話,真是玄之又玄,其實我們在之前的操作中已經接觸過這個狀態了,在**呢?在我們寫賣票的案例中,為了減少執行緒執行太快,現象不明顯等問題,我們在run方法中新增了sleep語句,這樣就強制當前正在執行的執行緒休眠(暫停執行),以「減慢執行緒」。其實當我們呼叫了sleep方法之後,當前執行的執行緒就進入到「休眠狀態」,其實就是所謂的timed waiting(計時等待),那麼我們通過乙個案例加深對該狀態的乙個理解。實現乙個計數器,計數到100,在每個數字之間暫停1秒,每隔10個數字輸出乙個字串**:
public class mythread extends thread
system.out.print(i);
try catch (interruptedexception e) }}
public static void main(string args)
}
通過案例可以發現, sleep方法的使用還是很簡單的。我們需要記住下面幾點:
進入 timed_waiting 狀態的一種常見情形是呼叫的 sleep 方法,單獨的執行緒也可以呼叫,不一定非要有協作關係。
為了讓其他執行緒有機會執行,可以將thread.sleep()的呼叫放執行緒run()之內。這樣才能保證該執行緒執行過程中會睡眠
開始立刻執行。(這裡我理解為執行緒排程的原因,例如時間片排程)
執行過程
blocked 狀態在api中的介紹為:乙個正在阻塞等待乙個監視器鎖(鎖物件)的執行緒處於這一狀態。我們已經學完同步機制,那麼這個狀態是非常好理解的了。比如,執行緒a與執行緒b**中使用同一鎖,如果執行緒a獲取到鎖,執行緒a進入到runnable狀態,那麼執行緒b就進入到blocked鎖阻塞狀態。這是由runnable狀態進入blocked狀態。除此waiting以及time waiting狀態也會在某種情況下進入阻塞狀態,而這部分內容作為擴充知識點帶領大家了解一下。
執行過程
wating狀態在api中介紹為:乙個正在無限期等待另乙個執行緒執行乙個特別的(喚醒)動作的執行緒處於這一狀態。那麼我們之前遇到過這種狀態嗎?答案是並沒有。我們通過一段**來學習一下:
public class mythread02 catch (interruptedexception e)
system.out.println(thread.currentthread().getname() "=== 繼續執行");
system.out.println(thread.currentthread().getname() "=== 從waiting狀態醒來,獲取到鎖物件,繼續執行了");
}// }
}}, "等待執行緒").start();
//name:喚醒執行緒
new thread(new runnable() catch (interruptedexception e)
synchronized (obj)
}// }
}, "喚醒執行緒").start();}}
通過上述案例我們會發現,乙個呼叫了某個物件的 object.wait 方法的執行緒會等待另乙個執行緒呼叫此物件的object.notify()方法 或 object.notifyall()方法。
其實waiting狀態並不是乙個執行緒的操作,它體現的是多個執行緒間的通訊,可以理解為多個執行緒之間的協作關係,多個執行緒會爭取鎖,同時相互之間又存在協作關係。就好比在公司裡你和你的同事們,你們可能存在晉公升時的競爭,但更多時候你們更多是一起合作以完成某些任務。
當多個執行緒協作時,比如a,b執行緒,如果a執行緒在runnable(可執行)狀態中呼叫了wait()方法那麼a執行緒就進入了waiting(無限等待)狀態,同時失去了同步鎖。假如這個時候b執行緒獲取到了同步鎖,在執行狀態中呼叫了notify()方法,那麼就會將無限等待的a執行緒喚醒。注意是喚醒,如果獲取到鎖物件,那麼a執行緒喚醒後就進入runnable(可執行)狀態;如果沒有獲取鎖物件,那麼就進入到blocked(鎖阻塞狀態)。
執行過程
一條有意思的tips:我們在翻閱api的時候會發現timed waiting(計時等待) 與 waiting(無限等待) 狀態聯絡還是很緊密的,比如waiting(無限等待) 狀態中wait方法是空參的,而timed waiting(計時等待) 中wait方法是帶參的。這種帶參的方法,其實是一種倒計時操作,相當於我們生活中的小鬧鐘,我們設定好時間,到時通知,可是如果提前得到(喚醒)通知,那麼設定好時間在通知也就顯得多此一舉了,那麼這種設計方案其實是一舉兩得。如果沒有得到(喚醒)通知,那麼執行緒就處於timed waiting狀態,直到倒計時完畢自動醒來;如果在倒計時期間得到(喚醒)通知,那麼執行緒從timed waiting狀態立刻喚醒。
本文由部落格一文多發平台 openwrite 發布!
後端開發之多執行緒Thread
多執行緒的好處 多執行緒解決了在乙個程序中同時可以執行多個任務 的問題。自定義執行緒的建立方式 方式一 繼承thread.為new mythread start 1.自定義乙個類繼承thread類。2.重寫thread的run方法,把自定義執行緒的任務 定義在run方法上。3.建立thread子類的...
多執行緒03 繼承Thread類
自定義執行緒類繼承thread類 重寫run 方法,編寫執行緒執行體 建立執行緒物件,呼叫start 方法啟動執行緒 package com.faq.demo01 建立執行緒方式一 繼承thread類,重寫run 方法,呼叫start開啟執行緒 總結 注意,執行緒的開啟不一定立即執行,由cpu排程執...
Python實戰之多執行緒程式設計thread模組
在python中除了可以通過繼承threading.thread類來實現多執行緒外,也可以呼叫thread模組中的start new thread 函式來產生新的執行緒,如下 import time,thread def timer print hello def test for i in ran...