2017年3月2日 星期四

優先權、join、yield、sleep、interrupt (Thread 三)

※優先權

public class ThreadTest extends Thread {
    @Override
    public void run() {
        System.out.println("name=" + Thread.currentThread().getName());
        System.out.println("priority=" + Thread.currentThread().getPriority());
    }
    
    public static void main(String... a) {
        Thread t = new Thread(new ThreadTest());
        t.start();
        t.setPriority(MAX_PRIORITY);
    }
}

※預設優先權為5,可設1~10的正整數,數字越大,優先權越高

※Thread 類別有三個field,MIN_PRIORITY、NORM__PRIORITY、MAX__PRIORITY,數字分別是 1、5、10,想設其他的就要自己寫死的了,但如果不在 1~10 裡,會出「java.lang.IllegalArgumentException」的錯



※join

哪一個 Thread 使用 join ,那就會先執行完自己的Thread,結束後才會執行其他的 Thread


public class ThreadTest extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 50; i++) {
            System.out.println("join=" + i);
        }
    }
    
    public static void main(String... a) {
        Thread t = new Thread(new ThreadTest());
        t.start();
    
        for (int i = 1; i <= 50; i++) {
            if (i == 10) {
                try {
                    t.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("main=" + i);
        }
    }
}

※i==10 後,會先將 join 的部分完成,最後才執行 main 的 Thread

※結果:
main=1
main=2
main=3
...
main=9
join=1
join=2
join=3
...
join=50
main=10
main=11
main=12
...
main=50



※yield

屈服的意思,是靜態方法,在哪個 Thread 寫 yield 就是哪個 Thread
使 Thread 讓出執行權,每個 Thread 會被分配到一小段 CPU 時間,時間結束就會換下一個 Thread,就算沒執行完也會換,如果執行這個方法,表示讓出執行權,讓其他 Thread 有機會執行,但也不是強制的


public class ThreadTest extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 50; i++) {
            if (i % 10 == 0) {
                Thread.yield();
            }
            System.out.println("yield=" + i);
        }
    }
    
    public static void main(String... a) {
        Thread t = new Thread(new ThreadTest());
        t.start();
    
        for (int i = 1; i <= 50; i++) {
            System.out.println("main=" + i);
        }
    }
}

※結果:
main=1
main=2
main=3
...
main=8
yield=1
yield=2
yield=3
...
yield=19
main=9
main=10
main=11
...
main=50
yield=20
yield=21
yield=22
...
yield=50

※以這個例子為例,一開始兩個 Thread 會互相取得執行權,10、20、30、40,yield 會讓 main 先執行,但因為不是強制的,所以10 並沒有換 main 執行,但到了20 就換 main 了,但 main 一口氣就執行完了,所以最後的30、40 也不用管 main 了



※sleep

sleep 和 yield 一樣,都是讓給其他 Thread 執行,也都是靜態方法


public class ThreadTest extends Thread {
    @Override
    public void run() {
        for (int i = 1; i <= 50; i++) {
            if (i % 10 == 0) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("sleep=" + i);
        }
    }
    
    public static void main(String... a) {
        Thread t = new Thread(new ThreadTest());
        t.start();
    
        for (int i = 1; i <= 50; i++) {
            System.out.println("main=" + i);
        }
    }
}

※結果:
main=1
main=2
main=3
sleep=1
main=4
main=5
main=6
...
main=18
sleep=2
sleep=3
sleep=4
...
sleep=9
main=19
main=20
main=21
...
main=45
sleep=10
main=46
main=47
main=48
main=49
main=50
sleep=11
sleep=12
sleep=13
...
sleep=50



※interrupt

public class ThreadTest extends Thread {
    @Override
    public void run() {
        try {
            System.out.println("1");
            Thread.sleep(5000);
            System.out.println("2");
        } catch (InterruptedException e) {
            System.out.println("3");
            // return;
        }
        System.out.println("4");
    }
    
    public static void main(String... a) {
        Thread t = new Thread(new ThreadTest());
        t.start();
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("5");
        t.interrupt();
        System.out.println("6");
    }
}

※結果:
1
5
3
4
6

※interrupt 後會被catch 攔截,但要注意如果沒有 return 或 break,還是會繼續執行



※yield 和 sleep 的差別

1.yield 不用參數,sleep 必需給參數
2.yield 只能讓同優先級的執行,但只是建議;sleep 不管優先級,只要是 Thread 就可執行
以上兩種方法不會釋放鎖
還有一個 Object 裡的 wait(),很像sleep,但會釋放鎖

沒有留言:

張貼留言