Thread常用方法的使用(二)

勿以惡小而爲之,勿以善小而不爲--------------------------劉備
勸諸君,多行善事積福報,莫作惡

上一章簡單介紹了 Thread和Runnable實現多線程(一),如果沒有看過,請觀看上一章

一. Thread 的靜態優先級常量

一.一 靜態常量

靜態常量
MAX_PRIORITY 最大優先級,值爲10
MIN_PRIORITY 最小優先級,值爲1
NORM_PRIORITY 默認優先級,值爲5

一. 二 演示 優先級常量

 @Test
    public void staticTest(){

        System.out.println("max:"+Thread.MAX_PRIORITY);
        System.out.println("norm:"+Thread.NORM_PRIORITY);
        System.out.println("min:"+Thread.MIN_PRIORITY);
    }

運行測試,查看控制檯:

有圖片

二. Thread 中方法

二.一 構造 方法

二.一.一 方法

方法 作用
Thread​() 默認,線程的名稱系統自定義
Thread​(String name) 用戶傳入唯一的線程名稱
Thread​(Runnable target) 傳入 runnable對象
Thread​(Runnable target, String name) 傳入runnable對象和唯一線程名稱name

二.一.二 演示構造方法

 @Test
    public void conTest(){

        //空構造
       Thread thread=new Thread();

		//傳入名稱 
        Thread thread1=new Thread("自定義線程");

        //傳入Runnable

        Thread thread2=new Thread(new MyRunnable());
        //4 傳入Runnable 和name


        Thread thread3=new Thread(new MyRunnable(),"自定義Runnable接口");
    }

二.二 其他方法

方法 作用
static Thread currentThread​() 獲取當前的運行線程
void setName​(String name) 設置線程的名稱,一般在線程運行之前設置
String getName​() 獲取線程的名稱
void setPriority​(int newPriority) 設置線程的優先級
int getPriority​() 獲取線程的優先級
Thread.State getState​() 獲取線程的狀態
boolean isAlive​() 判斷線程是否還活着
void setDaemon​(boolean on) 設置是否是守護線程,必須在未start 之前設置
boolean isDaemon​() 是否是守護線程
void interrupt​() 中斷線程
static boolean interrupted​() 線程是否已經中斷
boolean isInterrupted​() 是否被中斷
void join​() 讓此線程獲取資源,強制運行
static void sleep​(long millis) 優眠, 單位是毫秒
void start​() 開啓
static void yield​() 線程釋放資源,不首先運行

三. 演示線程名稱 getName()

@Test
    public void nameTest() throws Exception{

        NameThread nameThread=new NameThread();

        Thread thread1=new Thread(nameThread);

        //默認的爲 Thread-接下來的數據, 從0開始。

        Thread thread2=new Thread(nameThread,"自定義線程");

        Thread thread3=new Thread(nameThread);

        Thread thread4=new Thread(nameThread,"兩個蝴蝶飛,你好");
        thread1.start();

        thread2.start();
        thread3.start();

        thread4.start();
		
		// main,  main方法也是一個線程

        System.out.println("當前線程的名稱:"+Thread.currentThread().getName());
    }

    class NameThread implements  Runnable{

        @Override
        public void run() {
            for(int i=0;i<5;i++){
                System.out.println("當前線程:"+Thread.currentThread().getName()+"正在運行,輸出:"+i);
            }
        }
    }

運行程序,控制檯打印輸出

有圖片

如果不傳入線程的名稱, 則線程的名稱系統自分配爲: Thread-不重複數字

四. 獲取線程的信息

四.一 主線程狀態

  @Test
    public void readMainTest() throws Exception{

        //1. 獲取當前的主線程

        Thread thread=Thread.currentThread();

        System.out.println("當前線程的名稱:"+thread.getName());

        System.out.println("獲取標識符 id:"+thread.getId());

        System.out.println("獲取優先級:"+thread.getPriority());

        System.out.println("獲取狀態:"+thread.getState());

        System.out.println("當前線程是否還活着:"+thread.isAlive());

        System.out.println("是否被中斷:"+thread.isInterrupted());

        System.out.println("是否是守護線程:"+thread.isDaemon());

        //可以手動設置名稱和優先級

        thread.setName("手動設置名稱");

        thread.setPriority(Thread.MAX_PRIORITY);

        System.out.println("當前線程的名稱:"+thread.getName());

        System.out.println("獲取優先級:"+thread.getPriority());

        //設置守護線程,必須要在線程運行之前進行設置  

    }

運行程序,看控制檯輸出:

有圖片

四.二 Runnable 線程狀態


    @Test
    public void readNoTest() throws Exception{

        ReadRunnable readRunnable=new ReadRunnable();

        Thread thread=new Thread(readRunnable);

        thread.start();

    }

    class ReadRunnable implements  Runnable{
        @Override
        public void run() {
            Thread thread=Thread.currentThread();

            System.out.println("當前線程的名稱:"+thread.getName());

            System.out.println("獲取標識符 id:"+thread.getId());

            System.out.println("獲取優先級:"+thread.getPriority());

            System.out.println("獲取狀態:"+thread.getState());

            System.out.println("當前線程是否還活着:"+thread.isAlive());

            System.out.println("是否被中斷:"+thread.isInterrupted());

            System.out.println("是否是守護線程:"+thread.isDaemon());

            //可以手動設置名稱和優先級

            thread.setName("手動設置名稱");

            thread.setPriority(Thread.MAX_PRIORITY);
            

            System.out.println("當前線程的名稱:"+thread.getName());

            System.out.println("獲取優先級:"+thread.getPriority());

        }
    }

運行程序,控制檯打印輸出:

有圖片

五. 守護線程 setDaemon()

守護線程指的就是, 即使 Main 線程結束了, 此線程仍然會繼續運行。

五.一 設置守護線程

  @Test
    public void read3Test() throws Exception{

        Read3Runnable readRunnable=new Read3Runnable();

        Thread thread=new Thread(readRunnable);

        System.out.println("判斷是否啓動:"+thread.isAlive());

        System.out.println("是否是守護線程:"+thread.isDaemon());

        //在開啓之前設置
        thread.setDaemon(true);


        thread.start();

        System.out.println("是否啓動:"+thread.isAlive());

        System.out.println("是否是守護線程:"+thread.isDaemon());
    }


    class Read3Runnable implements  Runnable{
        @Override
        public void run() {
            System.out.println("獲取線程的名稱:"+Thread.currentThread().getName());
        }
    }

運行程序,控制檯打印輸出:

有圖片

五.二 守護線程

@Test
    public void daemonTest() throws Exception{

        DaemonRunnable daemonRunnable=new DaemonRunnable();

        Thread thread=new Thread(daemonRunnable);

        //先不是守護線程

        //啓動
       // thread.setDaemon(true);
        thread.start();



    }

   static class DaemonRunnable implements  Runnable{
        @Override
        public void run() {

            //死循環,會一直執行。 
            for(;;){
                System.out.println("我扣");
            }
        }
    }

此時運行, ,則運行一段時間之後,結束運行

有圖片

如果將註釋去掉,設置成守護線程的話,則會一直打印輸出。

有圖片

六. 線程的狀態 State

線程的狀態有以下幾種:

  1. NEW 尚未啓動的線程處於此狀態。
  2. RUNNABLE 在Java虛擬機中執行的線程處於此狀態。
  3. BLOCKED 被阻塞等待監視器鎖定的線程處於此狀態。
  4. WAITING 正在等待另一個線程執行特定動作的線程處於此狀態。
  5. TIMED_WAITING 正在等待另一個線程執行動作達到指定等待時間的線程處於此狀態。
  6. TERMINATED 已退出的線程處於此狀態。
   @Test
    public void readStateTest() throws Exception{

        ReadStateRunnable readRunnable=new ReadStateRunnable();

        Thread thread=new Thread(readRunnable);

         Thread.State state=thread.getState();

        System.out.println("開啓前狀態:"+state);

        thread.start();

        state=thread.getState();

        System.out.println("開啓後狀態:"+state);


    }


    class ReadStateRunnable implements  Runnable{
        @Override
        public void run() {
            System.out.println("獲取線程的名稱:"+Thread.currentThread().getName());
        }
    }

運行程序,控制檯打印輸出:

有圖片

七. 線程優眠 sleep

會暫停時間。

 //線程的休眠

    @Test
    public void sleepTest(){
        SleepRunnable readRunnable=new SleepRunnable();

        Thread thread=new Thread(readRunnable);

        thread.start();

        //休眠5秒, 保證後面的先不執行。
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("休眠結束,運行成功");


    }
    class SleepRunnable implements  Runnable{

        @Override
        public void run() {

            try {
                //暫時3秒後才輸出內容。
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("輸出線程名稱:"+Thread.currentThread().getName());
        }
    }

有圖片

八. 線程的強制執行 join()

讓這個線程強制最先執行。

 //線程的 join 方法
    @Test
    public void joinTest() throws Exception{

        JoinRunnable joinRunnable=new JoinRunnable();

        Thread thread=new Thread(joinRunnable);

        //啓動
        thread.start();

        // 主線程有10個,副線程100個,按理是 main先執行完, 加入了 join之後,強制讓副線程先執行完。
        for(int i=0;i<10;i++){

            //讓當前線程死掉.

            if(i==8){
                //當運行8後, 讓 thread線程強制運行,即到 i=8了,不運行了,讓 其他線程運行了。
                // 保證 i=8,i=9 最後輸出。
                thread.join();
            }
            System.out.println("當前線程:"+Thread.currentThread().getName()+"運行到:"+i);
        }
    }


    class JoinRunnable implements  Runnable{
        @Override
        public void run() {

            for(int i=0;i<100;i++){
                System.out.println("輸出內容:"+Thread.currentThread().getName()+",運行到:"+i);
            }
        }
    }

運行程序, 查看控制檯輸出:

有圖片

九. 線程的暫時掛起,不執行 yield()

注意, yield() 方法,只是讓此線程釋放資源,不執行,但不能保證最後執行。 可以線程 i=8時,得到了資源, 然後判斷了i>=7, 執行 .yield() 方法,釋放資源, 忽然它又得到了資源, 那麼i=8 就會運行了。 不像 join()那樣強制。

   @Test
    public void yieldTest() throws Exception{

        YieldRunnable yieldRunnable=new YieldRunnable();

        Thread thread=new Thread(yieldRunnable);

        //啓動
        thread.start();

        for(int i=0;i<100;i++){
            System.out.println("當前線程:"+Thread.currentThread().getName()+"運行到:"+i);
        }
    }


    class YieldRunnable implements  Runnable{
        @Override
        public void run() {
            Thread thread=Thread.currentThread();
            for(int i=0;i<10;i++){
                if(i>=7){
                    //級別設置小點, 讓其不執行。
                    thread.setPriority(Thread.MIN_PRIORITY);
                    Thread.yield();
                }
                System.out.println("輸出內容:"+thread.getName()+",運行到:"+i);
            }
        }
    }

運行程序,查看控制檯輸出

有圖片。

這兒的 i=7,i=8,i=9 就得到了資源,執行了,而不是強制最後執行。

十. 打斷休眠 interrupt()

主要用於 打斷 休眠。

@Test
    public void interTest() throws Exception{

        InterruptRunnable interruptRunnable=new InterruptRunnable();

        Thread thread=new Thread(interruptRunnable);

        //啓動

        thread.start();

        //休眠兩秒
        Thread.sleep(2000);

        //兩秒之後,進行打斷, 副線程應該還在休眠的狀態上。
        thread.interrupt();

        Thread.sleep(5000);

    }

    class InterruptRunnable implements  Runnable{
        @Override
        public void run() {

            System.out.println("開始進行休眠");

            try {
                Thread.sleep(5000);

                System.out.println("休眠結束");
            } catch (InterruptedException e) {
                System.out.println("休眠被打斷");
            }

            System.out.println("退出休眠");
        }
    }

運行程序,

有圖片

十.一 設置停止和重啓

以前 是有 stop() 這樣的方法的,後來被拋棄了, 用標誌位進行設置關閉和啓動。

class MyRunnableDemo implements Runnable{
    private boolean isRun=true;
    @Override
    public void run() {
        //定義此標識位
            while(isRun){
                try {
                    Thread.sleep(30);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("打印輸出");
            }
    }

    //通過標識位進行相應的控制
    public void stop(){
        this.isRun=false;
    }

    public void restart(){
        this.isRun=true;
        run();
    }
}
public class StopDemo {

    public static void main(String[] args) {
        MyRunnableDemo myRunnableDemo=new MyRunnableDemo();

        Thread thread=new Thread(myRunnableDemo);

        System.out.println("開始啓動");
        thread.start();

        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        myRunnableDemo.stop();
        System.out.println("停止");

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("重新啓動");
        myRunnableDemo.restart();

    }
}

運行程序,查看控制檯。

有圖片

這就是 Thread 類的常用方法,必須要掌握使用。


謝謝您的觀看,如果喜歡,請關注我,再次感謝 !!!
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章