最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java多線程之線程狀態(tài)的遷移詳解

 更新時間:2021年06月02日 14:55:53   作者:圣斗士Morty  
線程狀態(tài)遷移,又常被稱作線程的生命周期,指的是線程從創(chuàng)建到終結(jié)需要經(jīng)歷哪些狀態(tài),什么情況下會出現(xiàn)哪些狀態(tài).線程的狀態(tài)直接關(guān)系著并發(fā)編程的各種問題,本文就線程的狀態(tài)遷移做一初步探討,并總結(jié)在何種情況下會出現(xiàn)這些狀態(tài),需要的朋友可以參考下

一、六種狀態(tài)

java.lang.Thread 的狀態(tài)分為以下 6 種,它們以枚舉的形式,封裝在了Thread類內(nèi)部:

NEW:表示線程剛剛創(chuàng)建出來,還未啟動

RUNNABLE:可運行狀態(tài),該狀態(tài)的線程可以是ready或running,唯一的決定因素是線程調(diào)度器

BLOCKED:阻塞,線程正在等待一個monitor鎖以便進入一個同步代碼塊

WAITING:等待,一種掛起等待的狀態(tài)。一個線程處于waiting是為了等待其他線程執(zhí)行某個特定的動作。

TIMED_WAITING:定時等待。

TERMINATED:終結(jié),線程執(zhí)行結(jié)束后的狀態(tài)。

二、狀態(tài)遷移圖

線程遷移圖網(wǎng)上有很多,這是我自己參考著繪制的一張。

線程遷移圖雖然是背了忘忘了背,反反復(fù)復(fù)很多遍,但是記憶這張圖其實并不困難。首先就是NEW和TERMINATED狀態(tài),一個表示剛剛創(chuàng)建,一個表示任務(wù)結(jié)束。

最重要的是記住WAITING和BLOCKED這兩種狀態(tài)與RUNNABLE相互切換的條件。

BLOCKED狀態(tài)在Java doc中的描述是“等待一個monitor鎖”,monitor對象是與對象實例相關(guān)聯(lián)的一個鎖對象,這個鎖對象實際上就是 synchronized 的具體實現(xiàn),一般稱之為重量級鎖,進入同步代碼塊的過程,實際上就是獲取到 monitor 對象的鎖的過程。如果鎖被其他線程占用,當前線程就變成了BLOCKED狀態(tài),如果得到了鎖,就由BLOCKED切換到RUNNABLE狀態(tài)。

WAITING 是一種掛起狀態(tài),處于 waiting 的線程表示它正在等待一個有緣人~ 這個有緣人需要執(zhí)行特定的動作才能解救 waiting 中的線程。就像孫悟空在五指山下等了五百年,只有玄奘摘下山頂?shù)姆洳拍軌蚱仆炼觥?/p>

導致 WAITING 的情況只有三種:

wait()

join()

LockSupport.park()

wait() 方法是 Object 的成員方法,它可以令當前線程針對于某個對象掛起等待,并釋放獲得的鎖資源,只有當其他線程調(diào)用這個對象的notify()或 notifyAll() 方法,才能夠喚醒等待中的線程。注意,notify()或 notifyAll() 不會釋放鎖資源。

join() 方法是線程的一個成員方法,“加入一個線程”,這好像合情合理,比如 t1線程在執(zhí)行的過程中調(diào)用了 t2.join(),那么好吧, t1就會由 RUNNABLE 變?yōu)?WAITING,因為他要等待 t2 執(zhí)行完后才會繼續(xù)執(zhí)行,說白了,就是方便程序員讓線程插隊用的:

LockSupport.park()更方便,它是一個靜態(tài)方法,可以讓線程在調(diào)用的位置直接WAITING,然后在其他線程中,獲取到WAITING中的線程對象,傳入LockSupport(thread) 直接恢復(fù)運行。

三、線程狀態(tài)模擬

準備三個線程 monitor 監(jiān)視線程,主要實時監(jiān)視 t1線程的狀態(tài);

t1 線程模擬各種狀態(tài),t2 輔助 t1 模擬各種狀態(tài):

public class ThreadState {
    static Object lock = new Object();
    
    // 模擬 NEW、RUNNABLE、WAITING、TIMED_WAITING、BLOCKED、TERMINATED
    public static void main(String[] args) {
        ThreadState thisObj = new ThreadState();
        Thread t1 = new Thread(() -> {
            try {
                // 先獲取 t2 對象
                Thread t2 = getThreadByName("t2");
                // 先執(zhí)行一套邏輯,推遲同步代碼塊的調(diào)用
                String str = "";
                for (int i = 0; i < 10000; i++) {
                    str += i;
                }
                // 調(diào)用同步代碼塊
                thisObj.doSync();
                // t2準備插隊
                t2.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }, "t1");
        System.out.println("t1 剛創(chuàng)建:" + t1.getState());
        
        Thread t2 = new Thread(() -> {
            try {
                // 直接獲取同步鎖
                thisObj.doSync();
                // 釋放鎖后在運行一段時間
                TimeUnit.SECONDS.sleep(30);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }, "t2");
        
        Thread monitor = new Thread(() -> {
            Thread.State t1State = null;
            while (true) {
                if (!t1.getState().equals(t1State)) {
                    t1State = t1.getState();
                    System.out.println("t1 此刻狀態(tài):" + t1.getState());
                }
                if (t1State.equals(Thread.State.TERMINATED))
                    break;
            }
        }, "monitor");
        
        monitor.start();
        t2.start();
        t1.start();
    }
    
    public synchronized void doSync() {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        String str = "";
        for (int i = 0; i < 100000; i++) {
            str += i;
        }
    }
    
    public static Thread getThreadByName(String name) {
        Optional<Thread> first = Thread.getAllStackTraces()
                .keySet()
                .stream()
                .filter(thread -> thread.getName().equals(name))
                .findFirst();
        return first.get();
    }
}

輸出:

t1 剛創(chuàng)建:NEW
t1 此刻狀態(tài):RUNNABLE
t1 此刻狀態(tài):BLOCKED
t1 此刻狀態(tài):TIMED_WAITING
t1 此刻狀態(tài):TIMED_WAITING
t1 此刻狀態(tài):RUNNABLE
t1 此刻狀態(tài):WAITING
t1 此刻狀態(tài):BLOCKED
t1 此刻狀態(tài):TERMINATED

總結(jié)

線程狀態(tài)遷移是非常重要的多線程基礎(chǔ)知識,在調(diào)試多線程問題的時候,能夠發(fā)揮很大的作用。

6 種狀態(tài)不僅要熟記,而且在什么情況下會出現(xiàn)這些狀態(tài)也要清晰明了。

如果條件允許,可以試著通過不同的方法來模擬線程的六種狀態(tài)的切換,可以加深對線程生命周期的理解。

到此這篇關(guān)于Java多線程之線程狀態(tài)的遷移詳解的文章就介紹到這了,更多相關(guān)java線程狀態(tài)遷移內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 常用Maven庫,鏡像庫及maven/gradle配置(小結(jié))

    常用Maven庫,鏡像庫及maven/gradle配置(小結(jié))

    這篇文章主要介紹了常用Maven庫,鏡像庫及maven/gradle配置(小結(jié)),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-12-12
  • Java?8?Stream?處理數(shù)據(jù)方法匯總

    Java?8?Stream?處理數(shù)據(jù)方法匯總

    這篇文章主要介紹了Java?8?Stream處理數(shù)據(jù),Stream是Java?8?新引入的一個包它讓我們能用聲明式的方式處理數(shù)據(jù),Stream流式處理相較于傳統(tǒng)方法簡潔高效,也便于進行并發(fā)編程,更多相關(guān)內(nèi)容需要的小伙伴可以參考下面文章內(nèi)容
    2022-06-06
  • SpringBoot部署到外部Tomcat無法注冊到Nacos服務(wù)端的解決思路

    SpringBoot部署到外部Tomcat無法注冊到Nacos服務(wù)端的解決思路

    這篇文章主要介紹了SpringBoot部署到外部Tomcat無法注冊到Nacos服務(wù)端,本文給大家分享完美解決思路,結(jié)合實例代碼給大家講解的非常詳細,需要的朋友可以參考下
    2023-03-03
  • 微信公眾平臺(測試接口)準備工作

    微信公眾平臺(測試接口)準備工作

    想要微信開發(fā),首先要有個服務(wù)器,但是自己沒有。這時候可以用花生殼,將內(nèi)網(wǎng)映射到公網(wǎng)上,這樣就可以在公網(wǎng)訪問自己的網(wǎng)站了。
    2016-05-05
  • java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法

    java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法

    這篇文章主要介紹了java 如何往已經(jīng)存在的excel表格里面追加數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • javaCV開發(fā)詳解之收流器實現(xiàn)

    javaCV開發(fā)詳解之收流器實現(xiàn)

    這篇文章主要介紹了javaCV開發(fā)詳解之收流器實現(xiàn),對javaCV有研究的同學,可以參考下
    2021-04-04
  • Mybatis-plus分頁查詢不生效問題排查全過程

    Mybatis-plus分頁查詢不生效問題排查全過程

    最近寫分頁的時候,遇到了分頁無法正常發(fā)揮作用的問題,下面這篇文章主要給大家介紹了關(guān)于Mybatis-plus分頁查詢不生效問題排查的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下
    2023-03-03
  • java實現(xiàn)馬踏棋盤的算法

    java實現(xiàn)馬踏棋盤的算法

    這篇文章主要為大家詳細介紹了java實現(xiàn)馬踏棋盤的算法,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-02-02
  • Java的面向?qū)ο缶幊袒靖拍顚W習筆記整理

    Java的面向?qū)ο缶幊袒靖拍顚W習筆記整理

    這篇文章主要介紹了Java的面向?qū)ο缶幊袒靖拍顚W習筆記整理,包括類與方法以及多態(tài)等支持面向?qū)ο笳Z言中的重要特點,需要的朋友可以參考下
    2016-01-01
  • 淺談java面向?qū)ο?類,封裝,this,構(gòu)造方法)

    淺談java面向?qū)ο?類,封裝,this,構(gòu)造方法)

    下面小編就為大家?guī)硪黄獪\談java面向?qū)ο?類,封裝,this,構(gòu)造方法)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06

最新評論

台南县| 望城县| 平顶山市| 宁国市| 虹口区| 炎陵县| 昌图县| 黄平县| 铜梁县| 会东县| 铜梁县| 丹东市| 原阳县| 浦东新区| 芦山县| 淮滨县| 河西区| 姚安县| 慈利县| 新河县| 工布江达县| 大连市| 永定县| 阜康市| 乌鲁木齐市| 大渡口区| 高阳县| 安西县| 富源县| 曲周县| 黑龙江省| 德令哈市| 安庆市| 响水县| 卢龙县| 津南区| 犍为县| 夏邑县| 英吉沙县| 班戈县| 元氏县|