中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中線程的創建方式是什么

發布時間:2023-03-06 10:58:39 來源:億速云 閱讀:120 作者:iii 欄目:開發技術

本文小編為大家詳細介紹“Java中線程的創建方式是什么”,內容詳細,步驟清晰,細節處理妥當,希望這篇“Java中線程的創建方式是什么”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。

一. 繼承Thread

可以通過創建Thread的子類并在子類中重寫run() 方法完成線程創建。示例如下所示。

public class ThreadTest {

    @Test
    public void 繼承Thread() throws Exception {
        // 創建線程對象
        MyThread myThread = new MyThread();

        // 啟動線程
        myThread.start();

        // 睡1秒,等待子線程執行完任務
        Thread.sleep(1000);
    }

    private static class MyThread extends Thread {
        @Override
        public void run() {
            System.out.println("線程執行了");
        }
    }

}

運行測試程序,打印如下。

Java中線程的創建方式是什么

其實可以只繼承Thread,而不重寫run() 方法,此時是不會報錯的,只不過調用start() 方法后線程不會執行任何邏輯。示例如下。

public class ThreadTest {

    @Test
    public void 繼承Thread時可以不重寫run方法() {
        // 創建沒有重寫run()方法的線程對象
        MyThreadNotOverrideRun myThread = new MyThreadNotOverrideRun();

        // 啟動線程,不報錯,執行的是Thread的run()方法,無任何邏輯
        myThread.start();
    }

    private static class MyThreadNotOverrideRun extends Thread {}

}

二. 創建Runnable對象

可以通過創建Runnable接口的實現類,然后將Runnable對象作為Thread對象的執行任務,來創建線程。示例如下。

public class ThreadTest {

    @Test
    public void 基于Runnable() throws Exception {
        // 創建Runnable任務對象
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("任務執行");
            }
        };

        // 創建Thread對象時將Runnable任務對象通過構造函數傳入
        Thread thread = new Thread(runnable);

        // 啟動線程
        thread.start();

        // 睡1秒,等待子線程執行完任務
        Thread.sleep(1000);
    }

}

運行測試程序,執行結果如下所示。

Java中線程的創建方式是什么

三. 創建Callable對象

Callable接口也是可以作為任務被線程執行,其與Runnable接口的區別在于Callable任務可以有返回值,而Runnable任務沒有返回值。

由于Thread對象只能執行Runnable任務,因此無法直接讓Thread執行Callable任務,但是可以先將Callable封裝成FutureTask,而FutureTask是實現了Runnable接口的,所以Thread對象可以執行FutureTask任務。示例如下。

public class ThreadTest {

    @Test
    public void 基于Callable() throws Exception {
        // 創建Callable任務對象
        Callable<String> callable = new Callable<String>() {
            @Override
            public String call() throws Exception {
                return "任務執行結果";
            }
        };

        // 將Callable封裝成FutureTask
        FutureTask<String> futureTask = new FutureTask<>(callable);

        // 創建Thread對象時將FutureTask通過構造函數傳入
        Thread thread = new Thread(futureTask);

        // 啟動線程
        thread.start();

        // 通過FutureTask拿到執行結果
        System.out.println(futureTask.get());
    }

}

運行測試程序,結果如下。

Java中線程的創建方式是什么

四. 基于Runnable創建FutureTask

在第三小節中是基于Callable來創建的FutureTask,本小節將基于Runnable來創建FutureTask。在此之前,先看一下FutureTask的類圖,如下所示。

Java中線程的創建方式是什么

所以FutureTask即能夠作為Runnable被執行,也能夠作為Future獲取異步執行的結果。FutureTask有兩個構造函數,簽名如下。

// 基于Callable創建FutureTask
public FutureTask(Callable<V> callable)

// 基于Runnable創建FutureTask
public FutureTask(Runnable runnable, V result)

下面重點看一下如何基于Runnable創建FutureTask,源碼如下所示。

public FutureTask(Runnable runnable, V result) {
    // 使用Executors工具類將Runnable封裝成Callable
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;
}

繼續看Executors#callable(java.lang.Runnable, T) 方法,如下所示。

public static <T> Callable<T> callable(Runnable task, T result) {
    if (task == null) {
        throw new NullPointerException();
    }
    // 將Runnable封裝成RunnableAdapter
    return new RunnableAdapter<T>(task, result);
}

那么Executors#callable(java.lang.Runnable, T) 方法中就是將Runnable封裝成了RunnableAdapter,最后再看一下RunnableAdapter的實現。

static final class RunnableAdapter<T> implements Callable<T> {
    final Runnable task;
    final T result;
    
    RunnableAdapter(Runnable task, T result) {
        this.task = task;
        this.result = result;
    }
    
    public T call() {
        // 執行Runnable的邏輯
        task.run();
        // 執行完畢后,result作為結果返回
        return result;
    }
}

所以這里可以知道,基于Runnable創建FutureTask,其本質是將Runnable先封裝為Callable,然后再將Callable封裝成FutureTask。還有一點需要注意,在基于Runnable創建FutureTask時,除了傳入Runnable,還可以傳入一個作為返回結果的對象,Runnable執行完畢后,會將這個對象返回,這個對象也可以傳一個null,表示不需要返回值。

基于Runnable創建FutureTask的一個示例如下。

public class ThreadTest {

    @Test
    public void 基于Runnable來構建FutureTask() throws Exception {
        // 創建結果對象
        MyResult myResult = new MyResult();
        // 創建Runnable任務對象
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                myResult.setResult("任務執行");
            }
        };

        // 將Runnable封裝成FutureTask
        // Runnable執行后,會改變MyResult對象
        FutureTask<MyResult> futureTask = new FutureTask<>(runnable, myResult);

        // 創建Thread對象時將FutureTask通過構造函數傳入
        Thread thread = new Thread(futureTask);

        // 啟動線程
        thread.start();

        // 通過FutureTask拿到執行結果
        System.out.println(futureTask.get().getResult());
    }

    private static class MyResult {
        String result;

        public MyResult() {}

        public MyResult(String result) {
            this.result = result;
        }

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }
    }

}

運行測試程序,結果如下所示。

Java中線程的創建方式是什么

讀到這里,這篇“Java中線程的創建方式是什么”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

怀柔区| 庄浪县| 博兴县| 扬中市| 阳谷县| 陵水| 奉新县| 古田县| 襄樊市| 同江市| 玉田县| 剑川县| 类乌齐县| 饶阳县| 陇南市| 宝清县| 江城| 淮北市| 馆陶县| 平乡县| 社旗县| 阿城市| 巫溪县| 剑川县| 延寿县| 青海省| 周口市| 临高县| 和龙市| 桃园县| 平陆县| 朝阳县| 马边| 宁乡县| 嘉荫县| 秦安县| 渝北区| 六安市| 久治县| 开化县| 贡嘎县|