天天看點

建立多線程的方式

主線程:

  主線程即main線程,main方法是程式的入口,執行main方法時,JVM會找到作業系統開辟一條main方法通向CPU的執行路徑,CPU就可以通過該路徑來執行main方法。同樣的道理,當我們在main方法中開啟了新的線程時,JVM也會開辟新的路徑通向CPU,讓CPU可以通過新的路徑執行新的線程任務。且在JVM中,線程的排程是搶占式排程,即哪一個線程的優先度高,就執行哪個線程。

 了解Thread:

建立多線程的方式

Thread中常用的方法:

  public void start() :導緻此線程開始執行; Java虛拟機調用此線程的run方法。

  public String getName() :擷取目前線程名稱。

  public void setName() :設定此線程的名稱,等同于在子類中使用帶參的構造方法 Thread(String name)。

  public void run() :此線程要執行的任務在此處定義代碼。

  public static void sleep(long millis) :使目前正在執行的線程以指定的毫秒數暫停(暫時停止執行)。

  public static Thread currentThread() :傳回對目前正在執行的線程對象的引用。

對于上面的兩個靜态方法,直接使用Thread.方法()進行調用

第一種方式:建立一個類并繼承類Thread:

java.lang.Thread類:是描述線程的類,要想實作多線程,就必須繼承Thread類

實作步驟:

  1.建立一個Thread類的子類

  2.在該子類中重寫run方法,設定線程任務(即設定該線程做什麼)

  3.建立該子類對象

  4.子類對象調用Thread類中的start方法,開啟新的線程,此時就會自動執行子類中的run方法

 注意:若此時子類對象直接調用run方法,那麼是不會開啟新的線程的。

第二種方式:建立一個類并實作接口Runnable:

​Runnable​

​ 接口應該由那些打算通過某一線程執行其執行個體的類來實作。類必須定義一個稱為 ​

​run​

​ 的無參數方法。

  1.建立一個Runable接口的實作類

  2.在該實作類中重寫Runable接口的run()方法,設定線程任務(即設定該線程做什麼)

  3.建立一個實作類對象

  4.建立一個Thread對象,在構造方法中傳遞實作類對象作為參數

  5.Thread對象調用start()方法,開啟新線程執行run()方法

注意:實作了Runable接口後,依然需要Thread類去調用start()方法,才能開啟新線程。即Runnable實作類隻負責設定線程任務,

而開啟新線程的任務就交給了Thread類去完成,也就是實作了解耦。

知識點:

  1.public class Thread extends Objectimplements Runnable :Thread類其實也是實作了Runable接口

  2.通過實作Runnable接口,使得該類有了多線程類的特征。run()方法是多線程程式的一個執行目标。所有的多線程

代碼都在run方法裡面。Thread類實際上也是實作了Runnable接口的類。

  3.在啟動的多線程的時候,需要先通過Thread類的構造方法Thread(Runnable target) 構造出對象,然後調用Thread

對象的start()方法來運作多線程代碼。

  4.實際上所有的多線程代碼都是通過運作Thread的start()方法來運作的。是以,不管是繼承Thread類還是實作

Runnable接口來實作多線程,最終還是通過Thread的對象的API來控制線程的,熟悉Thread類的API是進行多線程

程式設計的基礎。

使用Runable開啟新線程的好處:

  1.避免單繼承的局限性:如果一個類繼承了Thread類,就不能再繼承其他類了。因為在java中,一個類隻能有一個父類,而實作的接口卻可以有很多個。

  2.增強程式的拓展性:實作了Runable接口後,就把設定線程任務和開啟新線程進行了分離,即實作了程式的解耦

第二種方式示例:

//    1.建立一個實作類,實作Runnable接口
public class MyRunnable implements Runnable {
//    2.重寫run()方法
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("你愛我,我愛你,蜜雪冰城甜蜜蜜"+i);
        }
    }
}      
public class TestMyRunnable {

    public static void main(String[] args) throws InterruptedException {
//        3.建立實作類對象
        MyRunnable mr = new MyRunnable();
//        4.建立Thread對象,并把實作類對象傳遞給其構造方法做參數
        Thread thread = new Thread(mr);
//        5.thread調用start方法,開啟新的線程
        thread.start();
//        調用getName()方法
        String name1 = thread.getName();
        System.out.println(name1);//Thread-0

//        開啟main線程
        for (int i = 0; i < 10; i++) {
            System.out.println("鴻星爾克好樣的!"+i);
        }

        //調用currentThread()方法
        String name2 = Thread.currentThread().getName();//main
        //調用sleep()方法,睡眠2秒鐘
        Thread.sleep(2000);
        System.out.println(name2);

    }
}      

我們發現上面的實作類其實可以用匿名内部類來實作。

使用匿名内部類:

public class NoNameInnerClass {
    public static void main(String[] args) {

//        1.使用匿名内部類,建立Runnable對象,并重寫run()方法
        Runnable mr = new Runnable() { //多态,子類對象指向父類。因為此時new Runnable(){}就相當于一個Runnable的實作類
            @Override
            public void run() {
                for (int i = 0; i < 10; i++) {
                    System.out.println("河南加油!!!"+i);
                }
            }
        };
//        2.建立Thread對象,并把Runnable對象傳遞給Thread對象
        Thread mt = new Thread(mr);
//        thread調用start()方法,開啟新線程
        mt.start();
    }
}      

繼續閱讀