Java多線程-線程狀態(tài)、優(yōu)先級(jí)

線程狀態(tài)

線程從開(kāi)啟到結(jié)束運(yùn)行,都有它自己的狀態(tài)。Thread類(lèi)中有一個(gè)枚舉類(lèi)可以表示所有的狀態(tài)。我們也把它們大致分成這幾個(gè)狀態(tài):

  1. 新建,線程剛new出來(lái)的時(shí)候
  2. 就緒,線程調(diào)用 start()
  3. 運(yùn)行,cpu執(zhí)行線程
  4. 阻塞,運(yùn)行中的線程因?yàn)槟承┎僮髦袛噙\(yùn)行,比如調(diào)用 sleep() 方法,阻塞完成后會(huì)回到就緒狀態(tài)
  5. 終止,線程的 run() 方法執(zhí)行完畢

Thread的枚舉類(lèi)State

  1. NEW,線程剛創(chuàng)建的狀態(tài)
  2. RUNNABLE,運(yùn)行中的線程
  3. BLOCKED,線程被阻塞的狀態(tài)
  4. WAITING,等待執(zhí)行的線程
  5. TIMED WAITING,等待sleep結(jié)束的線程
  6. TERMINATED,執(zhí)行完畢的線程

停止線程

不推薦直接調(diào)用線程的 stop() 方法來(lái)停止線程。

可以自己寫(xiě)一個(gè)boolean標(biāo)記來(lái)完成線程的停止:

package thread.situation;

public class StopDemo implements Runnable{
    private boolean flag=true;
    private int i=0;
    @Override
    public void run()
    {
        while(flag)
        {
            System.out.println("子線程執(zhí)行中..."+i++);
        }
    }
    public void stop()
    {
        flag = false;
    }

    //主方法
    public static void main(String[] args) {
        StopDemo s = new StopDemo();
        Thread t = new Thread(s);
        t.start();
        for (int i = 0; i < 100000000 ; i++)
        {
            System.out.println("Main Thread has execute"+i);
            if(i==9000000)
            {
                s.stop();
                System.out.println("Make the subthread stop...");
            }
        }
    }
}

線程的幾種方法:

  • sleep(100) 讓線程阻塞100毫秒,阻塞后回到就緒狀態(tài)
  • yield() 運(yùn)行中讓線程回到就緒狀態(tài),重新等待 cpu 的調(diào)用
  • join() 讓線程插隊(duì)執(zhí)行,插隊(duì)執(zhí)行的時(shí)候其它線程都會(huì)進(jìn)入阻塞狀態(tài),少用。

線程優(yōu)先級(jí)

前面已經(jīng)說(shuō)過(guò),調(diào)用就緒狀態(tài)的線程是由CPU內(nèi)部決定的,我們干預(yù)不了。但有時(shí)候,我們想讓某個(gè)線程優(yōu)先執(zhí)行怎么辦呢?我們可以向CPU提建議,也就是設(shè)置線程的優(yōu)先級(jí)。

Thread 類(lèi)中使用[1,10]來(lái)表示線程的優(yōu)先級(jí)。它還內(nèi)置了3個(gè)優(yōu)先級(jí)常量:MIN_PRIORITY、NORM_PRIORITY、MAX_PRIORITY,實(shí)際值分別是1,5,10。

我們可以在線程 start()調(diào)用它的 setPriority(int x) 方法設(shè)置優(yōu)先級(jí)來(lái)向CPU建議最好先執(zhí)行哪個(gè)線程(當(dāng)然CPU聽(tīng)不聽(tīng)就不知道了)。

使用 getPriority()方法可以查看當(dāng)前線程的優(yōu)先級(jí)。

package thread.situation;

public class StopDemo implements Runnable{

    @Override
    public void run()
    {
        System.out.println(Thread.currentThread().getName()+"優(yōu)先級(jí)是"+Thread.currentThread().getPriority());
    }
}
class Demo{
    public static void main(String[] args) throws InterruptedException {
        StopDemo s = new StopDemo();
        Thread t1 = new Thread(s,"最好的線程");
        Thread t2 = new Thread(s,"最差的線程");
        Thread t3 = new Thread(s,"有點(diǎn)好的線程");
        Thread t4 = new Thread(s,"有點(diǎn)差的線程");
        t1.setPriority(Thread.MAX_PRIORITY);
        t2.setPriority(Thread.MIN_PRIORITY);
        t3.setPriority(8);
        t4.setPriority(3);
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        System.out.println("主線程的優(yōu)先級(jí)是"+Thread.currentThread().getPriority());
    }
}

某次輸出結(jié)果:

主線程的優(yōu)先級(jí)是5
最差的線程優(yōu)先級(jí)是1
有點(diǎn)差的線程優(yōu)先級(jí)是3
最好的線程優(yōu)先級(jí)是10
有點(diǎn)好的線程優(yōu)先級(jí)是8

很明顯,CPU不太愿意接受我們的建議。

守護(hù)線程

線程其實(shí)是有兩種的。一種是用戶線程,一種是守護(hù)線程(Daemon)。用戶線程就是我們創(chuàng)建出來(lái)的線程,主線程也是用戶線程的一種。守護(hù)線程主要是一些服務(wù)線程,比如監(jiān)控內(nèi)存、垃圾回收線程之類(lèi)的。它們的區(qū)別在執(zhí)行方式上。

  • 如果是用戶線程,JVM會(huì)在所有的用戶線程執(zhí)行完后關(guān)機(jī)
  • 如果是服務(wù)線程...我都這么寫(xiě)了JVM會(huì)怎么對(duì)待守護(hù)線程不用我說(shuō)了吧(即使有守護(hù)線程在運(yùn)行,JVM還是會(huì)裝作看不到然后關(guān)機(jī))。

通過(guò)調(diào)用 Thread 類(lèi)的 setDeamon() 方法并傳入一個(gè) true 就可以把該類(lèi)變成守護(hù)線程了。

package thread.situation;

public class StopDemo implements Runnable{
    @Override
    public void run(){}
}
class Man implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("你"+i+"歲了");
        }
        System.out.println("http:////// ansl \\\\\\");
    }
}
class BigBrother implements Runnable{
    @Override
    public void run() {
        while(true) {
            for (int i = 0; i < 20000; i++)
            {
                System.out.println("Big Brother has watched you"+ i +"times");
            }

        }
    }
}
class Demo{
    public static void main(String[] args) throws InterruptedException {
        BigBrother bigBrother = new BigBrother();
        Man you = new Man();
        Thread brotherThread = new Thread(bigBrother);
        brotherThread.setDaemon(true);
        brotherThread.start();
        new Thread(you).start();
    }
}

最后一段輸出結(jié)果:

你99歲了
Big Brother has watched you54times
////// ansl \\\
Big Brother has watched you55times
Big Brother has watched you56times
Big Brother has watched you57times
Big Brother has watched you58times
Big Brother has watched you59times
Big Brother has watched you60times
Big Brother has watched you61times
Big Brother has watched you62times
Big Brother has watched you63times
Big Brother has watched you64times
Big Brother has watched you65times
Big Brother has watched you66times
Big Brother has watched you67times
Big Brother has watched you68times

Big Brother的循環(huán)還沒(méi)跑完,JVM就關(guān)機(jī)了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

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