天天看點

多線程,從start開始! | 帶你學《Java語言進階特性》之二

上一篇:靜看Java多線程之路如何直通羅馬 | 帶你學《Java語言進階特性》之一

【本節目标】

通過閱讀本節内容,你将了解到繼承Thread類并覆寫run方法的具體要求,并能夠通過執行個體化線程繼承類調用start方法開啟線程的過程中發生的變化。

如果想在Java中實作多線程的定義,那麼就需要有一個專門的線程主體類進行線程的執行任務的定義,而這個主體類的定義是有要求的,必須實作特定的接口或者繼承特定的父類才可以完成。

繼承Thead類實作多線程

Java裡面提供有一個java.lang.Thread的程式類,那麼一個類隻要繼承了此類就表示這個類為我們線程的主體類,但是并不是說這個類就可以實作多線程處理,因為還需要覆寫Thread類中提供的一個run()方法(public void run()),而這個方法就屬于線程的主方法。

範例:多線程主體類

class MyThread extends Thread {    //線程的主體類
    private String title;
    public MyThread(String title) {
        this.title = title;
    }
    @Override
    public void run() {   //線程的主體方法
        for (int x = 0; x < 10; x++) {
            System.out.println(this.title + "運作,x =" + x);
        }
    }
}           

多線程要執行的功能都應該在run()方法中進行定義。

需要說明的是:在正常情況下,如果想使用一個類中的方法,那麼肯定要産生執行個體化對象,而後去調用類中提供的方法,但是run()方法是不能夠被直接調用的,因為這裡面牽扯到一個作業系統資源排程問題,是以要想啟動多線程必須使用start()方法(public void start())完成。

範例:多線程啟動

public class ThreadDemo {
    public static void main(String[] args) {
        new MyThread("線程A").start();
        new MyThread("線程B").start();
        new MyThread("線程C").start();
    }
}           
多線程,從start開始! | 帶你學《Java語言進階特性》之二

圖一 啟動線程

通過此時的調用你可以發現,雖然調用了start()方法,但是最終執行的是run()方法,并且所有的線程對象都是交替執行的。

疑問:為什麼多線程的啟動不直接使用run()方法而必須使用Thread類中的start()方法呢?

如果要想清楚這個問題,最好的做法是檢視一下start()方法的實作操作,可以直接通過源代碼進行觀察。

public synchronized void start() {
    if (threadStatus != 0)     //判斷線程的狀态
    throw new IllegalThreadStateException();  //抛出一個異常
    group.add(this);
    boolean started = false;
    try {
          start0();    //在start()方法中調用了start0()
          started = true;
    } finally {
          try {
               if (!started) {
                  group.threadStartFailed(this);
               }
           } catch (Throwable ignore) {
           }
        }
    }
    private native void start0();    //隻定義了方法名稱,但沒有實作           

發現start()方法裡面會抛出一個IllegalThreadStateException異常類對象,但是整個程式中并沒有使用throws或者是明确的try..catch處理,因為該異常一定是RuntimeException的子類,每一個線程類的對象隻允許啟動一次,如果重複啟動則抛出IllegalThreadStateException異常,例如:下面的代碼就會抛出異常。

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread mt=  new MyThread("線程A");
        mt.start();
        mt.start();//重複進行了線程的啟動
    }
}           
多線程,從start開始! | 帶你學《Java語言進階特性》之二

圖二 抛出異常

在Java程式執行的過程之中,考慮到對于不同層次開發者的需求,是以其支援有本地的作業系統函數調用,而這項技術就被稱為JNI(Java Native Inteface)技術,但是Java開發過程中并不推薦這樣使用,利用這項技術可以使用一些作業系統提供的底層函數,進行一些特殊處理,而在Thread類中提供的start0()就表示需要将此方法依賴于不同的作業系統實作。

多線程,從start開始! | 帶你學《Java語言進階特性》之二

圖三 Thread的執行分析

任何情況下,隻要定義了多線程,多線程的啟動永遠隻有一種方案:Thread類中的start()方法。

想學習更多的Java的課程嗎?從小白到大神,從入門到精通,更多精彩不容錯過!免費為您提供更多的學習資源。

本内容視訊來源于

阿裡雲大學 下一篇:看Runnable如何巧避單繼承限制 | 帶你學《Java語言進階特性》之三 更多Java面向對象程式設計文章檢視此處