首頁  >  文章  >  Java  >  java中的多執行緒如何創建? (詳細)

java中的多執行緒如何創建? (詳細)

不言
不言原創
2018-09-25 15:32:011617瀏覽

本篇文章帶給大家的內容是關於java中的多執行緒如何創建? (詳細),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

什麼是執行緒:

執行緒是進程中的一個實體,是被系統獨立調度和分派的基本單位,執行緒自己不擁有系統資源,只擁有一點兒在運行中必不可少的資源,但它可與同屬一個進程的其它線程共享進程所擁有的全部資源

表面上是多線程其實是cpu快速輪流執行

多執行緒(並行與並發)

  1. 並行:兩個任務同事進行,就是甲任務執行的同時,乙任務也在執行(需要多核心)

  2. 並發:兩個任務都要求運行,而處理器只能接受一個任務,就把這兩個任務安排輪流執行。由於時間間隔很短,使人感覺兩個任務都在運行

多執行緒(java程式運行的原理)

java指令會啟動jvm等於啟動了一個應用程式(一個進程)。行程會自動啟動“主執行緒”,主執行緒去呼叫main方法

啟動jvm是單執行緒的麼?

不是,是多執行緒的。至少會啟動垃圾回收執行緒和主執行緒

可透過下面程式碼來驗證,主執行緒和垃圾回收執行緒在互相搶佔​​資源

public class TestThread {

    public static void main(String[] args) {
        //4.创建Thread的子类对象
        MyThread myThread = new MyThread();

        //5.启动线程,注意这里使用的是start而不是run方法
        myThread.start();

        for (int i = 0; i < 10000; i ++) {
            System.out.println("This is main thread");
        }
    }


}

//1.继承Thread
class MyThread extends  Thread{

    //2.重写run方法
    @Override
    public void run() {
        super.run();
        //3.线程方法中要执行的代码,可以根据自己的需求填写
        for(int i = 0 ; i < 10000 ; i ++ ) {
            System.out.println("This is MyThread thread ");
        }
    }
}

java中如何建立多執行緒

(1)繼承Thread類別並呼叫start方法

Thread實作了Runnable介面
要實作多線程,就要成為thread的子類,並且重寫run方法。注意在啟動執行緒的時候,呼叫的不是run方法而是start方法。如果呼叫run方法,那麼相當於一個普通方法並不會開啟線程

public class Thread implements Runnable
public class TestThread {

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        //注意这里使用的是start而不是run方法
        myThread.start();

        for (int i = 0; i < 10000; i ++) {
            System.out.println("This is main thread");
        }
    }
}
class MyThread extends  Thread{
    @Override
    public void run() {
        super.run();

        for(int i = 0 ; i < 10000 ; i ++ ) {
            System.out.println("This is MyThread thread ");
        }
    }
}

(2)實作runnable接口,並重寫run方法

Runnable中只有一個方法run(),而執行緒啟動方法存在與Thread中,
那麼我們在最終啟動執行緒的時候,勢必是要透過Thread的子類別物件去啟動執行緒的

public class TestRunnable {

    public static void main(String[] args) {
        //4.创建Thread的子类对象
        Runnable myRunnable = new MyRunnable();

        //5.启动线程,创建Thread并把runnable的子类作为构造参数
        new Thread(myRunnable).start();

        for (int i = 0; i < 10000; i ++) {
            System.out.println("This is main thread");
        }
    }

}
//1.实现runnable接口
class MyRunnable implements Runnable {

    //2.重写run方法
    @Override
    public void run() {
        //3.线程方法中要执行的代码,可以根据自己的需求填写
        for(int i = 0 ; i < 10000 ; i ++ ) {
            System.out.println("This is MyRunnable thread ");
        }
    }
}

實作Callable介面

#要實作線程,除了繼承thread和runnable,還可以實作Callable介面。 Callable介面提供了一個call()方法可以作為執行緒執行體,和run()的作用一樣。但call()方法比run()方法多了回傳值,call()方法可以宣告拋出的例外。那我們要如何開啟Callable執行緒呢?因為Callable介面不是Runnable介面的子介面,所以Callable物件不能作為Thread的建構參數。 Java提供了另一個介面RunnableFuture接口,該接口實作了Runnable, Future

  1. #實作Callable介面

  2. 重寫call方法,相當於thread中的run方法。不同的是call方法允許有回傳值

  3. 把Callable實作類別物件作為建構參數傳入FutureTask建立FutureTask物件。

  4. 把FutureTask物件當作建構參數傳入Thread,開啟執行緒

public class CallableDemo {

    public static void main(String[] args) {
        //3.把Callable实现类对象作为构造参数传入FutureTask创建FutureTask对象。
        FutureTask<UUID> futureTask = new FutureTask<UUID>(new MyCallable());
        //4.把FutureTask对象作为构造参数传入Thread,并开启线程
        new Thread(futureTask).start();
        try {
            System.out.println(futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }
}

//1. 实现**Callable**接口
class MyCallable implements Callable<UUID> {

    //2.重写**call**方法,相当于thread中的run方法。不同的是call方法允许有返回值
    @Override
    public UUID call() throws Exception {
        //生成随机数
        return UUID.randomUUID();
    }
}

繼承Thread,實作Runnable與Callable的差異

從原始碼的實作上

繼承Thread

子類別重寫Thread中的run()方法,呼叫start()方法,jvm會自動呼叫子類別的run()

實作Runnable

new Thread(myRunnable)在Thread的建構子中參入runnable的引用,然後傳給thread的成員變數target。在Thread run()方法中判斷如果target不為空,就呼叫子類別的run方法

    public void run() {
    if (this.target != null) {
        this.target.run();
    }

實作Callable介面

實作Callable介面重寫Call()方法,並且可以提供線程回傳值,也可以拋出異常。最後透過Runnable的子介面RunnableFuture的實作類別FutureTask,傳給Thread的成員變數target。

從使用上和拓展上

繼承Thread

  1. #優點:直接呼叫thread中的start()方法,十分簡單

  2. 缺點:java只支援單一繼承,如果子類別繼承了thread無法再繼承其他類別

實作Runnable

  1. 優點:java可以多實作

  2. 缺點:程式碼書寫比較複雜,不能直接呼叫start()

實作Callable

  1. 優點:java可以多實現,可以拋出異常,可以有回傳值

  2. 缺點:程式碼書寫比較複雜

以上是java中的多執行緒如何創建? (詳細)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn