1. 程式人生 > >【Java多執行緒程式設計核心技術】第一章(多執行緒技能 執行緒的優先順序)

【Java多執行緒程式設計核心技術】第一章(多執行緒技能 執行緒的優先順序)

1.8 執行緒的優先順序

 在作業系統中,執行緒可以劃分優先順序,優先順序較高的執行緒得到的cpu的資源較多,也就是cpu優先執行優先順序較高的執行緒物件中的任務.

 在Java中,執行緒優先順序分為1~10個等級,如果小於1大於10,則JDK丟擲異常,原始碼如下:

   public final void setPriority(int newPriority) {
        ThreadGroup g;
        checkAccess();
        if (newPriority > MAX_PRIORITY || newPriority < MIN_PRIORITY) {
            throw new IllegalArgumentException();
        }
        if((g = getThreadGroup()) != null) {
            if (newPriority > g.getMaxPriority()) {
                newPriority = g.getMaxPriority();
            }
            setPriority0(priority = newPriority);
        }
    }

測試用例:

public class PriorityThread1 extends Thread{
    @Override
    public void run() {
        System.out.println("PriorityThread1 run priority=" + this.getPriority());
        PriorityThread2 thread2 = new PriorityThread2();
        thread2.start();
    }
    public static void main(String[] args) {
        System.out.println("main thread begin priority = " + Thread.currentThread().getPriority());
//        Thread.currentThread().setPriority(6);
        System.out.println("main thread end priority =" + Thread.currentThread().getPriority());
        new PriorityThread1().start();
    }
}
public class PriorityThread2 extends Thread{
    @Override
    public void run() {
        System.out.println("PriorityThread2 run priority=" + this.getPriority());
    }
}

列印結果如下(優先順序被繼承):

main thread begin priority = 5
main thread end priority =5
PriorityThread1 run priority=5
PriorityThread2 run priority=5

去掉程式碼中的註釋列印結果如下(優先順序被修改繼續被繼承):

main thread begin priority = 5
main thread end priority =6
PriorityThread1 run priority=6
PriorityThread2 run priority=6

1.10.2 優先順序具有規則性

 雖然可以設定優先順序,但是沒有看到優先順序帶來的效果

public class PriorityThread1 extends Thread{
    @Override
    public void run() {
        long begin = System.currentTimeMillis();
        long addResult = 0;
        for(int i=0; i<10; i++){
            for(int j=0; j<50000; j++){
                Random random = new Random();
                random.nextInt();
                addResult = addResult + i;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("❤ ❤ ❤ ❤ ❤ thread1 use time " +(end - begin)+ " millisecond");
    }
    public static void main(String[] args) {
       for (int i=0; i<5; i++) {
           PriorityThread1 thread1 = new PriorityThread1();
           thread1.setPriority(10);
           thread1.start();
           PriorityThread2 thread2 = new PriorityThread2();
           thread2.setPriority(1);
           thread2.start();
       }
    }
}
public class PriorityThread2 extends Thread{
    @Override
    public void run() {
        long begin = System.currentTimeMillis();
        long addResult = 0;
        for(int i=0; i<10; i++){
            for(int j=0; j<50000; j++){
                Random random = new Random();
                random.nextInt();
                addResult = addResult + i;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("☆ ☆ ☆ ☆ ☆ thread2 use time " +(end - begin)+ " millisecond");
    }
}

列印結果如下:

☆ ☆ ☆ ☆ ☆ thread2 use time 217 millisecond
☆ ☆ ☆ ☆ ☆ thread2 use time 291 millisecond
❤ ❤ ❤ ❤ ❤ thread1 use time 302 millisecond
❤ ❤ ❤ ❤ ❤ thread1 use time 295 millisecond
❤ ❤ ❤ ❤ ❤ thread1 use time 320 millisecond
❤ ❤ ❤ ❤ ❤ thread1 use time 272 millisecond
❤ ❤ ❤ ❤ ❤ thread1 use time 338 millisecond
☆ ☆ ☆ ☆ ☆ thread2 use time 316 millisecond
☆ ☆ ☆ ☆ ☆ thread2 use time 286 millisecond
☆ ☆ ☆ ☆ ☆ thread2 use time 341 millisecond

由結果可以得知,高優先順序的執行緒總是大部分先執行完,但不代表高優先順序的執行緒全部執行完(也有可能是高優先順序的最後才執行完,但是大部分都是先執行的).另外不要以為高優先順序的執行緒被main執行緒呼叫就會先執行完,出現這樣的結果全是因為其優先順序是最高值10造成的.但執行緒優先順序的等級差距很大時,誰先執行完和程式碼的呼叫順序無關,cpu儘量將執行資源讓給優先順序高的執行緒.

1.10.3 優先順序具有隨機性

 前面案例介紹了執行緒的優先順序較高則優先執行完run()方法中的任務,但這個結果不能說的太肯定,因為執行緒的優先順序還具有隨機性,也就是優先順序較高的執行緒不一定每一次都先執行完

1.11 守護執行緒

在Java執行緒中有兩種執行緒,一種是使用者執行緒,另一種是守護執行緒.守護執行緒是一種特殊的執行緒,當程序中不存在非守護執行緒了,則守護執行緒自動銷燬.典型的守護執行緒就是垃圾回收執行緒.用這個比較通俗的比喻來解釋一下"守護執行緒":任何一個守護執行緒都是整個JVM中所有非守護執行緒的保姆,只要當前的JVM例項中存在任何一個非守護執行緒沒有結束,守護執行緒就在工作,只有當最後一個非守護執行緒結束時,守護執行緒才隨著JVM一同結束工作.Daemon的作用就是為其它執行緒的執行提供便利服務,守護執行緒最典型的應用就是GC,它是一個很稱職的守護者

public class DaemonThread extends Thread{
    private static int count = 0;
    @Override
    public void run() {
        while(true) {
            try {
                count ++;
                System.out.println(count);
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        try {
            DaemonThread thread = new DaemonThread();
            thread.setDaemon(true);
            thread.start();
            Thread.sleep(5000);
            System.out.println("main thread is exist, so daemon is stop working");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}