java Thread狀態(tài)深入了解

線程

線程是進(jìn)程中的一個單一順序的執(zhí)行單元,也被稱為輕量進(jìn)程(lightweight process)。線程有自己的必須資源擎椰,同時與其他線程進(jìn)程共享全部資源。同一個進(jìn)程中创肥,線程是并發(fā)執(zhí)行的达舒。由于線程的之間的相互制約,線程有就緒叹侄、阻塞巩搏、運行、結(jié)束等狀態(tài)趾代。

java中的線程

在java中運行一個線程很簡單贯底,通過繼承Thread或者實現(xiàn)Runnable接口就可以創(chuàng)建一個線程。

class MyThread exends Thread{
    
    @Override
    public void run(){

    }
}

class MyRunnable implements Runnable{

    @Override
    public void run(){

    }   
}

啟動一個線程

public static void main(String agrs[]){
    new MyThread().start();//繼承啟動
    new Thread(new MyRunnable()).start();//接口啟動
}

驗證java線程的并發(fā)性

在各自的run方法中 for循環(huán)輸出 各自的名稱

    for(int i=0;i<100;i++){
        System.out.println("this is implements Runnable");
    }

    for(int i=0;i<100;i++){
        System.out.println("this is extends Thread");
    }

線程鎖

下面方法執(zhí)行后,數(shù)據(jù)少于1w

public static void ThreadMuliteTest() throws InterruptedException {
        final List<String> list=new ArrayList();
        for(int i=0;i<10000;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        console.info("等20s");
        Thread.sleep(20000);
        System.out.println(list.size());
}

線程如果同時執(zhí)行就會產(chǎn)生一個問題 他們看到list里的數(shù)據(jù)是一樣多的撒强,插入的時候就會互相抵掉對方插入的數(shù)據(jù)禽捆,解決辦法是排隊,加鎖

public static void ThreadMuliteTest() throws InterruptedException {
        final List<String> list=new ArrayList();
        for(int i=0;i<10000;i++){
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (list) {
                        list.add(Thread.currentThread().getName());
                    }
                }
            }).start();
        }
        console.info("等20s");
        Thread.sleep(20000);
        System.out.println(list.size());
}

死鎖

當(dāng)線程互相等待對方釋放自己需要的資源時 就會產(chǎn)生死鎖

public static void diedLock(){
        Object lock1=new Object();
        Object lock2=new Object();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock1){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    synchronized (lock2){
                        console.info("運行了飘哨!");
                    }
                }
            }
        }).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (lock2){
                    synchronized (lock1){
                        console.info("運行了睦擂!");
                    }
                }
            }
        }).start();
    }

java線程的狀態(tài)

線程狀態(tài)圖
  • NEW 新建狀態(tài)
    new 之后 start之前 都是屬于NEW狀態(tài),一旦狀態(tài)變成其他 則不會再回到NEW狀態(tài)
  • BLOCKED 阻塞狀態(tài)
    如果獲取不到鎖 則進(jìn)入阻塞狀態(tài) 直到獲取到鎖之后
  • RUNNABLE 執(zhí)行狀態(tài)
    在run方法里的時候 線程處于執(zhí)行狀態(tài) 一旦run方法結(jié)束 則狀態(tài)不再是執(zhí)行狀態(tài)
  • WAITING 等待狀態(tài)
    wait調(diào)用后杖玲,睡眠不參與搶鎖 等待notify喚醒
  • TIMED_WAITING 等待超時狀態(tài)
    當(dāng)調(diào)用wait(long timeout)方法時 線程處于等待狀態(tài) 超時后并不返回 而是等待獲取鎖后返回
  • TERMINATED 結(jié)束狀態(tài)
    在run方法結(jié)束后線程處于結(jié)束狀態(tài)

public static void stateTest() throws InterruptedException {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                long startTime=System.nanoTime();
                /**
                 * Thread.currentThread() 獲取當(dāng)前線程
                 * Thread.currentThread()===t true
                 * 打印當(dāng)前線程狀態(tài)
                 */
                printThreadState(Thread.currentThread());
                synchronized (lock){
                    try {
                        lock.wait();//放棄搶鎖 處于WATING狀態(tài)
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                console.info(System.nanoTime()-startTime+"納秒");
            }
        });
        printThreadState(t);//查看new之后的thread狀態(tài)
        synchronized (lock) {
            t.start();
            while (true) {
                printThreadState(t);//查看thread狀態(tài)
                if (t.getState() == Thread.State.TERMINATED) {
                    break;
                } else if (t.getState() == Thread.State.TIMED_WAITING) {
                    synchronized (lock) {
                        Thread.sleep(20000);
                    }
                } else if (t.getState() == Thread.State.WAITING) {
                    synchronized (lock) {
                        lock.notify();//通知wait的線程 醒來搶鎖
                    }
                } else if(t.getState()== Thread.State.BLOCKED){
                    lock.wait(100);//喚醒阻塞的線程
                    continue;
                }
                Thread.sleep(100);//休眠100ms
            }
        }
    }

喚醒線程

當(dāng)線程處于TIMED_WAITING狀態(tài)的時候 可以調(diào)用interrupt喚醒它* NEW 新建狀態(tài)

public static void awakeThread() throws InterruptedException {
        Thread t=new Thread(new Runnable() {
            @Override
            public void run() {
                long startTime=System.currentTimeMillis();
                try {
                    synchronized (lock) {
                        lock.wait(20000);//Thread.sleep(20000) thread.join()  lock.wait();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                console.info("喚醒成功顿仇!"+(System.currentTimeMillis()-startTime)+"s");
            }
        });
        t.start();
        Thread.sleep(100);
        t.interrupt();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市摆马,隨后出現(xiàn)的幾起案子臼闻,更是在濱河造成了極大的恐慌,老刑警劉巖囤采,帶你破解...
    沈念sama閱讀 211,042評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件述呐,死亡現(xiàn)場離奇詭異,居然都是意外死亡蕉毯,警方通過查閱死者的電腦和手機乓搬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,996評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來代虾,“玉大人进肯,你說我怎么就攤上這事∶弈ィ” “怎么了江掩?”我有些...
    開封第一講書人閱讀 156,674評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我环形,道長策泣,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,340評論 1 283
  • 正文 為了忘掉前任抬吟,我火速辦了婚禮萨咕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘火本。我一直安慰自己危队,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,404評論 5 384
  • 文/花漫 我一把揭開白布发侵。 她就那樣靜靜地躺著交掏,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刃鳄。 梳的紋絲不亂的頭發(fā)上盅弛,一...
    開封第一講書人閱讀 49,749評論 1 289
  • 那天,我揣著相機與錄音叔锐,去河邊找鬼挪鹏。 笑死,一個胖子當(dāng)著我的面吹牛愉烙,可吹牛的內(nèi)容都是我干的讨盒。 我是一名探鬼主播,決...
    沈念sama閱讀 38,902評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼步责,長吁一口氣:“原來是場噩夢啊……” “哼返顺!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起蔓肯,我...
    開封第一講書人閱讀 37,662評論 0 266
  • 序言:老撾萬榮一對情侶失蹤遂鹊,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蔗包,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體秉扑,經(jīng)...
    沈念sama閱讀 44,110評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年调限,在試婚紗的時候發(fā)現(xiàn)自己被綠了舟陆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,577評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡耻矮,死狀恐怖秦躯,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情淘钟,我是刑警寧澤宦赠,帶...
    沈念sama閱讀 34,258評論 4 328
  • 正文 年R本政府宣布陪毡,位于F島的核電站米母,受9級特大地震影響勾扭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜铁瞒,卻給世界環(huán)境...
    茶點故事閱讀 39,848評論 3 312
  • 文/蒙蒙 一妙色、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧慧耍,春花似錦身辨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,726評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至泌豆,卻和暖如春定庵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背踪危。 一陣腳步聲響...
    開封第一講書人閱讀 31,952評論 1 264
  • 我被黑心中介騙來泰國打工蔬浙, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贞远。 一個月前我還...
    沈念sama閱讀 46,271評論 2 360
  • 正文 我出身青樓畴博,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蓝仲。 傳聞我的和親對象是個殘疾皇子俱病,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,452評論 2 348

推薦閱讀更多精彩內(nèi)容