1. 程式人生 > >Java執行緒——執行緒控制基本方法

Java執行緒——執行緒控制基本方法

執行緒操作基本方法

isAlive() 判斷執行緒是否還未終止 getPriority() 獲取執行緒的優先順序數值,返回值 setPriority() 設定執行緒的優先順序 Thread.sleep() 將當前執行緒睡眠指定毫秒數 join()

呼叫某執行緒的該方法,將當前執行緒與該執行緒“合併”,等待該執行緒結束,再恢復當前執行緒的執行

yield()

讓出cpu,當前執行緒進入就緒佇列等待排程

wait()

當前執行緒進去物件的等待佇列(wait pool)

notify()/notifyAll() 喚醒物件的wait pool 中的一個或所有等待執行緒

sleep/join/yield方法介紹

sleep方法

import java.util.*;

public class TestThread3 {

    public static void main(String args[]){

        MyThread thread = new MyThread();

        thread.start();//呼叫start()方法啟動新開闢的執行緒

        try {

            /*Thread.sleep(10000);

            sleep()方法是在Thread類裡面宣告的一個靜態方法,因此可以使用Thread.sleep()的格式進行呼叫

            */

            /*MyThread.sleep(10000);

            MyThread類繼承了Thread類,自然也繼承了sleep()方法,所以也可以使用MyThread.sleep()的格式進行呼叫

            */

            /*靜態方法的呼叫可以直接使用“類名.靜態方法名”

              或者“物件的引用.靜態方法名”的方式來呼叫*/

            MyThread.sleep(10000);

            System.out.println("主執行緒睡眠了10秒種後再次啟動了");

            //在main()方法裡面呼叫另外一個類的靜態方法時,需要使用“靜態方法所在的類.靜態方法名”這種方式來呼叫

            /*

            所以這裡是讓主執行緒睡眠10秒種

            在哪個執行緒裡面呼叫了sleep()方法就讓哪個執行緒睡眠,所以現在是主執行緒睡眠了。

            */

        } catch (InterruptedException e) {

            e.printStackTrace();

        }

        //thread.interrupt();//使用interrupt()方法去結束掉一個執行緒的執行並不是一個很好的做法

        thread.flag=false;//改變迴圈條件,結束死迴圈

        /**

         * 當發生InterruptedException時,直接把迴圈的條件設定為false即可退出死迴圈,

         * 繼而結束掉子執行緒的執行,這是一種比較好的結束子執行緒的做法

         */

        /**

         * 呼叫interrupt()方法把正在執行的執行緒打斷

        相當於是主執行緒一盆涼水潑上去把正在執行分執行緒打斷了

        分執行緒被打斷之後就會拋InterruptedException異常,這樣就會執行return語句返回,結束掉執行緒的執行

        所以這裡的分執行緒在執行完10秒鐘之後就結束掉了執行緒的執行

         */

    }

}

class MyThread extends Thread {

    boolean flag = true;// 定義一個標記,用來控制迴圈的條件

    public void run() {

        /*

         * 注意:這裡不能在run()方法的後面直接寫throw Exception來拋異常, 

         * 因為現在是要重寫從Thread類繼承而來的run()方法,重寫方法不能丟擲比被重寫的方法的不同的異常。

         *  所以這裡只能寫try……catch()來捕獲異常

         */

        while (flag) {

            System.out.println("==========" + new Date().toLocaleString() + "===========");

            try {

                /*

                 * 靜態方法的呼叫格式一般為“類名.方法名”的格式去呼叫 在本類中宣告的靜態方法時呼叫時直接寫靜態方法名即可。 當然使用“類名.方法名”的格式去呼叫也是沒有錯的

                 */

                // MyThread.sleep(1000);//使用“類名.方法名”的格式去呼叫屬於本類的靜態方法

                sleep(1000);//睡眠的時如果被打斷就會丟擲InterruptedException異常

                // 這裡是讓這個新開闢的執行緒每隔一秒睡眠一次,然後睡眠一秒鐘後再次啟動該執行緒

                // 這裡在一個死迴圈裡面每隔一秒啟動一次執行緒,每個一秒打印出當前的系統時間

            } catch (InterruptedException e) {

                /*

                 * 睡眠的時一盤冷水潑過來就有可能會打斷睡眠 

                 * 因此讓正在執行執行緒被一些意外的原因中斷的時候有可能會拋被打擾中斷(InterruptedException)的異常

                 */

                return;

                // 執行緒被中斷後就返回,相當於是結束執行緒

            }

        }

    }

}

join方法

public class TestThread4 {
    public static void main(String args[]) {
        MyThread2 thread2 = new MyThread2("mythread");
        // 在建立一個新的執行緒物件的同時給這個執行緒物件命名為mythread
        thread2.start();// 啟動執行緒
        try {
            thread2.join();// 呼叫join()方法合併執行緒,將子執行緒mythread合併到主執行緒裡面
            // 合併執行緒後,程式的執行的過程就相當於是方法的呼叫的執行過程
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am main Thread");
        }
    }
}

class MyThread2 extends Thread {
    MyThread2(String s) {
        super(s);
        /*
         * 使用super關鍵字呼叫父類的構造方法 
         * 父類Thread的其中一個構造方法:“public Thread(String name)” 
         * 通過這樣的構造方法可以給新開闢的執行緒命名,便於管理執行緒
         */
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println("I am a\t" + getName());
            // 使用父類Thread裡面定義的
            //public final String getName(),Returns this thread's name.
            try {
                sleep(1000);// 讓子執行緒每執行一次就睡眠1秒鐘
            } catch (InterruptedException e) {
                return;
            }
        }
    }
}

yield方法

public class TestThread5 {
    public static void main(String args[]) {
        MyThread3 t1 = new MyThread3("t1");
        /* 同時開闢了兩條子執行緒t1和t2,t1和t2執行的都是run()方法 */
        /* 這個程式的執行過程中總共有3個執行緒在並行執行,分別為子執行緒t1和t2以及主執行緒 */
        MyThread3 t2 = new MyThread3("t2");
        t1.start();// 啟動子執行緒t1
        t2.start();// 啟動子執行緒t2
        for (int i = 0; i <= 5; i++) {
            System.out.println("I am main Thread");
        }
    }
}

class MyThread3 extends Thread {
    MyThread3(String s) {
        super(s);
    }

    public void run() {
        for (int i = 1; i <= 5; i++) {
            System.out.println(getName() + ":" + i);
            if (i % 2 == 0) {
                yield();// 當執行到i能被2整除時當前執行的執行緒就讓出來讓另一個在執行run()方法的執行緒來優先執行
                /*
                 * 在程式的執行的過程中可以看到,
                 * 執行緒t1執行到(i%2==0)次時就會讓出執行緒讓t2執行緒來優先執行 
                 * 而執行緒t2執行到(i%2==0)次時也會讓出執行緒給t1執行緒優先執行
                 */
            }
        }
    }
}

Tip:在執行程式碼的時候可以做試幾次,會發現每次出現的結果都不一樣,是因為cpu排程策略的關係