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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容