java 多線程基礎(四)

1、線程組(ThreadGroup)

    一個系統中,若是線程數量不少,並且功能呢個分配比較明確,就能夠將相同功能的線程放置在一個線程組裏。打個比方,若是你有一本書,你就能夠把它拿在手裏,可是若是你有十本書,你就最好找一個書包,不然不方便攜帶。對於線程也是同等道理,若是你想處理十個或是上百個線程,最好仍是將他們都裝進對應的書包裏。java

    線程組使用很是簡單以下:ide

public class DiscoveryApplicaion {
    public static volatile int i = 0;
    static class Plustask implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getThreadGroup().getName()+"-"+Thread.currentThread().getName());
            for (int k = 0; k < 1000; k++) {
                i++;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread[] task = new Thread[10];
        ThreadGroup group = new ThreadGroup("Group1");
        for (int j = 0; j <task.length ; j++) {
            task[j] = new Thread(group,new Plustask(),"T"+j);
            task[j].start();
            task[j].join();
        }
        System.out.println(group.activeCount());
        group.list();
        System.out.println(i);
    }
}

    線程組中有幾個比較關鍵的方法,有助於你調試lua

  • activeCount:能夠得到活動線程的總數,但因爲線程是動態的,所以這個值只是一個估計值,沒法肯定精確。
  • list:能夠打印這個線程組中的全部的線程信息,對調試有必定幫組。
  • stop:它會中止線程組中全部的線程。看起開是一個很方便的功能。可是它會遇到和Thread.stop相同的問題,所以使用時需格外當心。

    注:強烈建議你們在建立線程組的時候,給取一個好聽的名字。若是你在調試時拿到的是一堆Thread-0、Thread-1我想你們必定會抓狂的。spa

2、守護線程(Daemon)

    守護線程是一種特殊的線程,就和它的名字同樣,他是系統的守護者,在後臺默默的完成一些系統性的服務。好比垃圾回收線程、JIT線程就能夠理解爲守護線程。與之相對應的是用戶線程,用戶線程能夠認爲是系統的工做線程,它會完成這個程序應該要完成的業務操做。若是用戶線程所有結束,這也意味着這個程序實際上無事可作了。守護線程要守護的對象已經不存在了,那麼整個應用程序就天然應該結束。所以,當一個java應用內,只有守護線程時,java虛擬機就會天然退出。 操作系統

public class DiscoveryApplicaion {
    public static volatile int i = 0;
    static class Plustask implements Runnable{
        @Override
        public void run() {
            while (true){
                System.out.println("i am alive");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
//        SpringApplication.run(DiscoveryApplicaion.class, args);
        Thread aa = new Thread(new Plustask());
        aa.setDaemon(true);
        aa.start();
        Thread.sleep(2000);
    }
}

    這裏要注意,設置守護線程必須在線程start()以前設置,不然你會獲得如下異常,告訴你守護線程設置失敗,但線程依然能夠正常執行。只是被看成用戶線程而已。線程

Exception in thread "main" java.lang.IllegalThreadStateException
	at java.lang.Thread.setDaemon(Thread.java:1352)
	at Controller.DiscoveryApplicaion.main(DiscoveryApplicaion.java:28)

    若是你不當心將setDaemon設置在了start()之後,那你就會詫異爲何程序永遠不會停下來呢。調試

3、線程優先級(Priority)

    優先級高的線程在競爭資源時會有更有優點,更可能搶佔資源,固然這只是機率問題。若是運氣很差,高優先級線程可能也會搶佔失敗。因爲線程的優先級調度和底層操做系統有密切關係,在各個平臺上表現不一,而且這種優先級產生的後果也可能不容易預測,沒法精確控制。數字越大則優先級越高,但有效範圍在1~10之間code

public class DiscoveryApplicaion {
    public final static int MIN_PRIORITY = 1;
    public final static int NORM_PRIORITY = 5;
    public final static int MAX_PRIORITY = 10;
    static class HightPriority extends Thread{
        static int count = 0;
        public void run() {
            while (true){
                synchronized (DiscoveryApplicaion.class){
                    count++;
                    if (count > 100000){
                        System.out.println("HightPriority 優先處理完成");
                        break;
                    }
                }
            }
        }
    }
    static class LowPriority extends Thread{
        static int count = 0;
        public void run() {
            while (true){
                synchronized (DiscoveryApplicaion.class){
                    count++;
                    if (count > 100000){
                        System.out.println("LowPriority 優先處理完成");
                        break;
                    }
                }
            }
        }
    }
    public static void main(String[] args) throws InterruptedException {
        Thread hight = new HightPriority();
        Thread low = new LowPriority();
        low.setPriority(MAX_PRIORITY);
        hight.setPriority(MIN_PRIORITY);
        low.start();
        hight.start();
    }
}

    能夠嘗試執行上述代碼,能夠看到,高優先級的線程在大部分狀況下,都會首先完成任務。(但這不能確保全部狀況下,必定都是這樣)對象

相關文章
相關標籤/搜索