Java多線程編程(一)

從今天開始開始多了解一些Java多線程的有關知識,自己在腦海中好好做個整理,Java多線程也是一個十分容易出問題的地方。在簡書中看見一位大牛推薦的Java多線程書籍《Java多線程編程核心技術》,這本書感覺還不錯,適合自己,就從這里開始吧。

[TOC]

Thread常用方法

方法名稱 方法作用
currentThread(靜態) 返回對當前正在執行的線程對象的引用
isAlive 判斷當前的線程是否處于活動狀態
sleep(靜態) 讓當前正在執行的線程休眠
getId 取得線程的唯一標識

** 注意:** 活動狀態是指線程已經啟動且尚未終止。

告訴你真相:

class MyThread extends Thread{
        public MyThread(){
            System.out.println("thread name = " + Thread.currentThread().getName());
        }

        public  void run(){
            System.out.println("thread name = " + Thread.currentThread().getName());
        }
}

public class Demo{
    public static void main(String[] args) throws Exception{
        MyThread thread = new MyThread();
        thread.start();
    }
}

運行結果:

thread name = main
thread name = Thread-0

這里主要說明Thread的實例化是在主線程中進行的,只有run方法會在自己的線程中自動被調用。

知道了一種比較好用的停止線程手段。開心ing(interrupt 英 [?nt?'r?pt] 中斷 我去!又是個難記得word)

在實現之前先了解下Thread類的三個方法

方法名稱 方法作用
interrupt 中斷線程
interrupted(靜態) 測試當前線程是否已經是中斷狀態,執行后具有將狀態標志清除為false的功能
isInterrupted 測試線程Thread對象是否已經是中斷狀態,但是不清楚狀態標志
class MyThread extends Thread{
        public  void run(){
            try{
                for(int i = 0; i < 1000000; i++){
                    if (Thread.interrupted()) { // 判斷當前線程是否中斷
                        throw new InterruptedException();
                    }
                    System.out.println("i = " + i);
                }
            }catch(Exception e){
                e.printStackTrace();
            }
    }
}

public class Demo{
    public static void main(String[] args) throws Exception{
        MyThread thread = new MyThread();
        thread.start();
        Thread.sleep(10);
        thread.interrupt(); // 停止線程
    }
}

運行結果:

i = 0
i = 1
i = 2
i = 3
i = 4
i = 5
i = 6
i = 7
i = 8
i = 9
i = 10
i = 11
i = 12
i = 13
i = 14
i = 15
i = 16
i = 17
i = 18
i = 19
i = 20
java.lang.InterruptedException
        at MyThread.run(Demo.java:10)

啊哈就這么簡單的實現了線程的停止,而且用異常的方式還可以將信息傳遞回去,這樣是不是very nice?。

Java多線程的優先級(Priority 吐槽一下,這詞真難記)

啊哦,Java多線程具有哪些特色呢?(小二,優先級有啥特色,快快拿來嘗嘗鮮)

  • 繼承特性(這里可不是說誰繼承誰,它要說明的是當一個線程啟動另一個線程的默認情況下,它們的優先級一樣)
  • 規則性(同時執行的多個線程,優先級大的線程先被執行的可能性更高)
  • 隨機性(表示并不一定優先級高,就一定先執行它)

繼承特性Test:

class ThreadParent extends Thread{
        public  void run(){
            System.out.println("ThreadParent priority = " +this.getPriority());
      this.setPriority(8); // 這里有故事
            ThreadChild childThread = new ThreadChild();
            childThread.start();
        }
}

class ThreadChild extends Thread{
    public void run(){
        System.out.println("ThreadChild priority = " +this.getPriority());
    }
}

public class Demo{
    public static void main(String[] args) throws Exception{
        System.out.println("main Thread priority start = " + Thread.currentThread().getPriority());
        Thread.currentThread().setPriority(6);
        System.out.println("main Thread priority end = " + Thread.currentThread().getPriority());
        ThreadParent thread = new ThreadParent();
        thread.start();
    }
}

Test結果:

main Thread priority start = 5
main Thread priority end = 6
ThreadParent priority = 6
ThreadChild priority = 8

可以看到事實確實如此。不過這里我測試發現,當一個線程啟動另一個線程的時候,它的優先級是在實例化另一個線程的時候完成的。因為如果你將上面的第四行this.setPriority(8)放到第五行下面,你會發現ThreadChild的優先級還是6。(具體的為什么就需要你去發掘啦~)

Java多線程有倆種

  • 用戶線程
  • 守護線程(daemon 這是個新單詞哦(發音:英 ['di?m?n] (迪們)))

守護線程最大的特點就是,只有當 所有的非守護線程Over 了,它才會Over。
書中舉了個最好的例子就是Java的垃圾回收器是個守護線程。

那我們如何讓一個線程變成守護線程呢?

非常簡單,只需要調用Thread實例的setDaemon()。

接下來用代碼說話!

class MyRunnable implements Runnable{
        public  void run(){
            while(true){ //  這里寫了一個死循環
                for (int i = 0; i < 5; i++) {
                    System.out.println("I am DaemonThread: "+Thread.currentThread().getName());
                }
            }
        }
}

public class Demo{
    public static void main(String[] args) throws Exception{
        MyRunnable runable = new MyRunnable();
        Thread myThread = new Thread(runable);
        myThread.setDaemon(true); // 將線程設置為守護線程
        myThread.start();
        Thread.sleep(1000);
        System.out.println("MainThread Over!");
    }
}

輸出結果:

I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
I am DaemonThread: Thread-0
MainThread Over!
I am DaemonThread: Thread-0

從上面的代碼中我們可以看到守護線程要執行的是一個無線循環,如果是用戶線程它將會一直執行下去,但是守護線程則不同。main線程執行完后,守護線程也GG了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容