Java多線程之線程狀態(tài)詳解
線程狀態(tài)
五個狀態(tài):新生
、就緒
、運行
、死亡
、阻塞
停止線程
- 不推薦使用JDK提供的stop()、destroy()方法【已棄用】
- 推薦線程自己停止
- 建議用一個標志位進行終止變量,到flag=false,則終止線程運行
public class StopDemo implements Runnable { // 設(shè)置一個標志位 boolean flag = true; @Override public void run() { // 線程體使用該標志 while (flag) { System.out.println("runing...."); } } // 設(shè)置一個公共的方法停止線程,轉(zhuǎn)換標志位 public void stop() { this.flag = false; } }
線程休眠
- sleep(時間)指定當前線程阻塞的毫秒數(shù)
- sleep存在異常 Interrupted Exception
- sleep時間達到后線程進入就緒狀態(tài)
- sleep可以模擬網(wǎng)絡(luò)延時,倒計時等
- 每一個對象都有一個鎖,sleep不會釋放鎖(重點記下)
模擬網(wǎng)絡(luò)延遲(放大問題的發(fā)生性)
搶票:
public class SleepDemo implements Runnable { // 票數(shù) private int tickeNum = 10; @Override public void run() { while (true) { if (tickeNum <= 0) { break; } try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(String.format("%s --> 拿到了第%d張票", Thread.currentThread().getName(), tickeNum--)); } } public static void main(String[] args) { SleepDemo sleepDemo = new SleepDemo(); new Thread(sleepDemo, "張三").start(); new Thread(sleepDemo, "李四").start(); new Thread(sleepDemo, "王五").start(); } }
從輸出結(jié)果看,第4張票被多個人搶到了,產(chǎn)生了線程安全問題
模擬計時
public class SleepDemo2 { // 模擬倒計時 public static void countDown() { int num = 5; while (true) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm:ss"))); num--; if (num==0) { break; } } } public static void main(String[] args) { countDown(); } }
線程禮讓
- 禮讓線程,讓當前正在執(zhí)行的線程暫停,但不阻塞
- 將線程從運行狀態(tài)轉(zhuǎn)為就緒狀態(tài)
- 讓CPU重新調(diào)度,禮讓不一定成功!看CPU心情
public class YieldDemo { public static void main(String[] args) { MyYeild myYeild = new MyYeild(); new Thread(myYeild, "a").start(); new Thread(myYeild, "b").start(); } } class MyYeild implements Runnable { @Override public void run() { System.out.println(Thread.currentThread().getName() + " 線程開始"); // 禮讓 Thread.yield(); System.out.println(Thread.currentThread().getName() + " 線程停止"); } }
如果a線程禮讓成功了,就會讓b線程先跑
插隊(線程強制執(zhí)行)
- Join合并線程,待此線程執(zhí)行完成后,再執(zhí)行其他線程,其他線程阻塞
- 可以想象成食堂插隊打飯。會讓線程阻塞,慎用。
public class JoinDemo implements Runnable { @Override public void run() { for (int i = 0; i < 1000; i++) { System.out.println("vip來了" + i); } } public static void main(String[] args) throws InterruptedException { JoinDemo joinDemo = new JoinDemo(); Thread thread = new Thread(joinDemo); thread.start(); // 主線程 for (int i = 0; i < 500; i++) { if (i == 200) { // 插隊 thread.join(); } System.out.println("main" + i); } } }
在主線程中的i=100的時候,vip線程進來插隊,直到vip執(zhí)行完,主線程才繼續(xù)
線程狀態(tài)觀測
通過一個枚舉常量:Thread.State
public class StateDemo { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(() -> { for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("==========="); } }); // 觀察狀態(tài) new System.out.println(thread.getState()); // 啟動后 run thread.start(); System.out.println(thread.getState()); // 只要線程不終止,就一直輸出狀態(tài) while (thread.getState() != Thread.State.TERMINATED) { Thread.sleep(500); System.out.println(thread.getState()); } } }
線程優(yōu)先級
- Java提供一個線程調(diào)度器來監(jiān)控程序中啟動后進入就緒狀態(tài)的所有線程,線程調(diào)度器按照優(yōu)先級決定應(yīng)該調(diào)度哪個線程來執(zhí)行
- 線程的優(yōu)先級用數(shù)字表示,范圍從1~10
- Thread.MIN PRIORITY = 1;
- Thread.MAX PRIORITY = 10;
- Thread.NORM PRIORITY = 5;
- 使用以下方式改變或獲取優(yōu)先級
- getPriority()、setPriority(int xxx)
不一定線程優(yōu)先級高的會先跑,優(yōu)先級低也只是意味著獲得調(diào)度的概率低,并不是優(yōu)先級低就不會被調(diào)用了,主要還是取決于CPU調(diào)度,有可能會出現(xiàn)性能倒置。
守護線程
線程分為用戶線程和守護線程
虛擬機必須確保用戶線程執(zhí)行完畢
虛擬機不用等待守護線程執(zhí)行完畢
如,后臺記錄操作日志,監(jiān)控內(nèi)存,垃圾回收,一些等待機制等等
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java將CSV的數(shù)據(jù)發(fā)送到kafka的示例
這篇文章主要介紹了Java將CSV的數(shù)據(jù)發(fā)送到kafka得示例,幫助大家更好得理解和使用Java,感興趣的朋友可以了解下2020-11-11Spring Cloud Feign實現(xiàn)文件上傳下載的示例代碼
Feign框架對于文件上傳消息體格式并沒有做原生支持,需要集成模塊feign-form來實現(xiàn),本文就詳細的介紹一下如何使用,感興趣的可以了解一下2022-02-02啟動springboot應(yīng)用因未配置數(shù)據(jù)庫報錯的解決方案
這篇文章主要介紹了啟動springboot應(yīng)用因未配置數(shù)據(jù)庫報錯的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11Java實現(xiàn)迷你圖書管理系統(tǒng)案例全程
這篇文章主要為大家詳細介紹了如何利用java語言實現(xiàn)簡單的圖書管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-12-12使用MyBatis攔截器實現(xiàn)sql查詢權(quán)限動態(tài)修改代碼實例
這篇文章主要介紹了使用MyBatis攔截器實現(xiàn)sql查詢權(quán)限動態(tài)修改代碼實例,為了不耦合,現(xiàn)在的方案是在需要鑒權(quán)的Mybatis?Mapper方法上增加一個注解,在運行過程中判斷該注解存在即對sql進行修改,需要的朋友可以參考下2023-08-08詳解springcloud 基于feign的服務(wù)接口的統(tǒng)一hystrix降級處理
這篇文章主要介紹了詳解springcloud 基于feign的服務(wù)接口的統(tǒng)一hystrix降級處理,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-06-06