Java并發(fā)編程之線程狀態(tài)介紹
線程狀態(tài)概述
線程由生到死的完整過程:
當線程被創(chuàng)建并啟動以后,它既不是一啟動就進入了執(zhí)行狀態(tài),也不是一直處于執(zhí)行狀態(tài)。在線程的生命周期中,有幾種狀態(tài)呢?在API中java.lang.Thread.State
這個枚舉中給出了六種線程狀態(tài):
線程狀態(tài) | 導致狀態(tài)發(fā)生條件 |
---|---|
NEW(新建) | 線程剛被創(chuàng)建,但是并未啟動。還沒調用start方法。MyThread t = new MyThread只有線程對象,沒有線程特征。 |
Runnable(可運行) | 線程可以在java虛擬機中運行的狀態(tài),可能正在運行自己代碼,也可能沒有,這取決于操作系統(tǒng)處理器。調用了t.start()方法 :就緒(經典教法) |
Blocked(鎖阻塞) | 當一個線程試圖獲取一個對象鎖,而該對象鎖被其他的線程持有,則該線程進入Blocked狀態(tài);當該線程持有鎖時,該線程將變成Runnable狀態(tài)。 |
Waiting(無限等待) | 一個線程在等待另一個線程執(zhí)行一個(喚醒)動作時,該線程進入Waiting狀態(tài)。進入這個狀態(tài)后是不能自動喚醒的,必須等待另一個線程調用notify或者notifyAll方法才能夠喚醒。 |
Timed Waiting(計時等待) | 同waiting狀態(tài),有幾個方法有超時參數(shù),調用他們將進入Timed Waiting狀態(tài)。這一狀態(tài)將一直保持到超時期滿或者接收到喚醒通知。帶有超時參數(shù)的常用方法有Thread.sleep 、Object.wait。 |
Teminated(被終止) | 因為run方法正常退出而死亡,或者因為沒有捕獲的異常終止了run方法而死亡。 |
睡眠sleep方法
狀態(tài)中有一個狀態(tài)叫做計時等待,可以通過Thread類的方法來進行演示。 public static void sleep(long time)
讓當前線程進入到睡眠狀態(tài),到毫秒后自動醒來繼續(xù)執(zhí)行
//主線程執(zhí)行到sleep方法會休眠1秒后再繼續(xù)執(zhí)行 public class Test{ public static void main(String[] args){ for(int i = 1;i<=5;i++){ Thread.sleep(1000); System.out.println(i) } } }
等待和喚醒
public void wait()
: 讓當前線程進入到等待狀態(tài) 此方法必須鎖對象調用。
public class Demo1_wait { public static void main(String[] args) throws InterruptedException { // 步驟1 : 子線程開啟,進入無限等待狀態(tài), 沒有被喚醒,無法繼續(xù)運行. new Thread(() -> { try { System.out.println("begin wait ...."); synchronized ("") { "".wait(); } System.out.println("over"); } catch (Exception e) { } }).start(); }
public void notify()
: 喚醒當前鎖對象上等待狀態(tài)的線程 此方法必須鎖對象調用。
public class Demo2_notify { public static void main(String[] args) throws InterruptedException { // 步驟1 : 子線程開啟,進入無限等待狀態(tài), 沒有被喚醒,無法繼續(xù)運行. new Thread(() -> { try { System.out.println("begin wait ...."); synchronized ("") { "".wait(); } System.out.println("over"); } catch (Exception e) { } }).start(); //步驟2: 加入如下代碼后, 3秒后,會執(zhí)行notify方法, 喚醒wait中線程. Thread.sleep(3000); new Thread(() -> { try { synchronized ("") { System.out.println("喚醒"); "".notify(); } } catch (Exception e) { } }).start(); } }
等待喚醒的一個小例子
定義一個集合,包子鋪線程完成生產包子,包子添加到集合中;吃貨線程完成購買包子,包子從集合中移除。
- 當包子沒有時(包子狀態(tài)為false),吃貨線程等待.
- 包子鋪線程生產包子(即包子狀態(tài)為true),并通知吃貨線程(解除吃貨的等待狀態(tài))
public class BaoZiPu extends Thread{ private List<String> list ; public BaoZiPu(String name,ArrayList<String> list){ super(name); this.list = list; } @Override public void run() { int i = 0; while(true){ //list作為鎖對象 synchronized (list){ if(list.size()>0){ //存元素的線程進入到等待狀態(tài) try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //如果線程沒進入到等待狀態(tài) 說明集合中沒有元素 //向集合中添加元素 list.add("包子"+i++); System.out.println(list); //集合中已經有元素了 喚醒獲取元素的線程 list.notify(); } } } } }
public class ChiHuo extends Thread { private List<String> list ; public ChiHuo(String name,ArrayList<String> list){ super(name); this.list = list; } @Override public void run() { //為了能看到效果 寫個死循環(huán) while(true){ //由于使用的同一個集合 list作為鎖對象 synchronized (list){ //如果集合中沒有元素 獲取元素的線程進入到等待狀態(tài) if(list.size()==0){ try { list.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } //如果集合中有元素 則獲取元素的線程獲取元素(刪除) list.remove(0); //打印集合 集合中沒有元素了 System.out.println(list); //集合中已經沒有元素 則喚醒添加元素的線程 向集合中添加元素 list.notify(); } } } } }
public class Demo { public static void main(String[] args) { //等待喚醒案例 List<String> list = new ArrayList<>(); // 創(chuàng)建線程對象 BaoZiPu bzp = new BaoZiPu("包子鋪",list); ChiHuo ch = new ChiHuo("吃貨",list); // 開啟線程 bzp.start(); ch.start(); } }
到此這篇關于Java并發(fā)編程之線程狀態(tài)介紹的文章就介紹到這了,更多相關Java 線程狀態(tài)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
簡單介紹區(qū)分applet和application的方法
applet和application都是Java語言編寫出來的應用程序,本文簡單介紹了二者的不同之處,需要的朋友可以參考下2017-09-09springboot框架阿里開源低代碼工具LowCodeEngine
這篇文章主要為大家介紹了springboot框架阿里開源低代碼LowCodeEngine工具使用詳解有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-06-06SpringBoot 下的 Static 文件夾打包成前端資源的示例代碼
這篇文章主要介紹了SpringBoot 下的 Static 文件夾如何打包成前端資源,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-06-06spring+springmvc+mybatis 開發(fā)JAVA單體應用
這篇文章主要介紹了spring+springmvc+mybatis 開發(fā)JAVA單體應用的相關知識,本文通過圖文實例代碼的形式給大家介紹的非常詳細 ,需要的朋友可以參考下2018-11-11Java String、StringBuffer與StringBuilder的區(qū)別
本文主要介紹Java String、StringBuffer與StringBuilder的區(qū)別的資料,這里整理了相關資料及詳細說明其作用和利弊點,有需要的小伙伴可以參考下2016-09-09