最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JDK8中線程實(shí)現(xiàn)的本質(zhì)與最佳實(shí)踐指南

 更新時(shí)間:2025年12月22日 16:44:31   作者:樂觀甜甜圈  
本文探討了JDK8中線程實(shí)現(xiàn)的唯一本質(zhì),并對比了Thread類和Runnable接口的區(qū)別,文中指出,在JDK8中,創(chuàng)建線程的本質(zhì)是實(shí)例化Thread類并調(diào)用其start()方法,而所謂的“不同方式”只是執(zhí)行邏輯的不同策略,感興趣的朋友跟隨小編一起看看吧

一、揭開線程實(shí)現(xiàn)的"唯一性"迷霧

1.1 表面上的"多種方式"

在JDK8中,開發(fā)者通常認(rèn)為有兩種創(chuàng)建線程的方式:

  • 繼承Thread類并重寫run()方法
  • 實(shí)現(xiàn)Runnable接口并傳遞給Thread構(gòu)造器

還有第三種變體:實(shí)現(xiàn)Callable接口配合FutureTask。然而,這真的是三種不同的方式嗎?

1.2 追蹤Thread類的源碼真相

讓我們深入JDK8的Thread類源碼,揭示本質(zhì):

// Thread.java (JDK8源碼節(jié)選)
public class Thread implements Runnable {
    private Runnable target;
    public Thread() {
        init(null, null, "Thread-" + nextThreadNum(), 0);
    }
    public Thread(Runnable target) {
        init(null, target, "Thread-" + nextThreadNum(), 0);
    }
    @Override
    public void run() {
        if (target != null) {
            target.run();  // 調(diào)用傳遞的Runnable
        }
    }
}

關(guān)鍵發(fā)現(xiàn)

  • Thread類本身實(shí)現(xiàn)了Runnable接口
  • Thread內(nèi)部維護(hù)一個(gè)Runnable類型的target字段
  • 默認(rèn)的run()方法會(huì)檢查target,不為空則調(diào)用其run()方法
  • 繼承Thread類時(shí),重寫的run()方法覆蓋了默認(rèn)實(shí)現(xiàn)

1.3 線程創(chuàng)建的唯一本質(zhì)

// 三種方式的本質(zhì)都是創(chuàng)建Thread對象并調(diào)用start()
// 方式1:繼承Thread類
Thread thread1 = new CustomThread();  // CustomThread extends Thread
thread1.start();
// 方式2:實(shí)現(xiàn)Runnable接口
Runnable runnable = new CustomRunnable();  // CustomRunnable implements Runnable
Thread thread2 = new Thread(runnable);
thread2.start();
// 方式3:實(shí)現(xiàn)Callable接口(間接)
Callable<String> callable = new CustomCallable();  // CustomCallable implements Callable
FutureTask<String> futureTask = new FutureTask<>(callable);
Thread thread3 = new Thread(futureTask);  // FutureTask實(shí)現(xiàn)了RunnableFuture,而RunnableFuture繼承了Runnable
thread3.start();

核心結(jié)論
在JDK8中,創(chuàng)建線程本質(zhì)上只有一種方式:實(shí)例化Thread類并調(diào)用其start()方法。所謂的"不同方式"只是定義線程執(zhí)行邏輯(run()方法)的不同策略。

二、Thread類與Runnable接口的解剖對比

2.1 Thread類的實(shí)現(xiàn)結(jié)構(gòu)

// Thread類的簡化繼承關(guān)系
public class Thread implements Runnable {
    // 線程狀態(tài)、優(yōu)先級(jí)、棧大小等屬性
    // 大量native方法:start0(), stop0(), sleep0()等
    
    // 關(guān)鍵:Thread本身就是一個(gè)Runnable
}

2.2 兩種方式的執(zhí)行流程對比

// 場景1:繼承Thread類
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("繼承方式");
    }
}
// 執(zhí)行流程:
// 1. 創(chuàng)建MyThread實(shí)例
// 2. 調(diào)用start() → 創(chuàng)建系統(tǒng)線程 → 調(diào)用run()
// 3. 由于重寫了run(),直接執(zhí)行自定義邏輯
// 場景2:實(shí)現(xiàn)Runnable接口
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Runnable方式");
    }
}
// 執(zhí)行流程:
// 1. 創(chuàng)建Thread實(shí)例,傳入MyRunnable
// 2. 調(diào)用start() → 創(chuàng)建系統(tǒng)線程 → 調(diào)用Thread.run()
// 3. Thread.run()檢查target不為null → 調(diào)用target.run()
// 4. 執(zhí)行MyRunnable的run()方法

三、為什么Runnable接口方式更優(yōu)秀?

3.1 避免繼承的局限性:單繼承約束

// 問題場景:需要繼承業(yè)務(wù)類,又想擁有線程能力
class BusinessService {
    public void doBusiness() {
        // 業(yè)務(wù)邏輯
    }
}
// 錯(cuò)誤示例:無法同時(shí)繼承Thread
// class BusinessThread extends BusinessService, Thread { } // 編譯錯(cuò)誤
// 正確方案:使用Runnable
class BusinessThread extends BusinessService implements Runnable {
    @Override
    public void run() {
        // 線程邏輯
        doBusiness();
    }
}
// 使用
Thread thread = new Thread(new BusinessThread());
thread.start();

優(yōu)勢:Java是單繼承語言,使用Runnable可以避免繼承Thread而無法繼承其他業(yè)務(wù)類的限制。

3.2 職責(zé)分離:符合單一職責(zé)原則

// 不良設(shè)計(jì):Thread子類承擔(dān)多重職責(zé)
class DownloadThread extends Thread {
    private String url;
    private String savePath;
    public DownloadThread(String url, String savePath) {
        this.url = url;
        this.savePath = savePath;
    }
    @Override
    public void run() {
        // 1. 下載邏輯(業(yè)務(wù)職責(zé))
        // 2. 線程調(diào)度(線程職責(zé))
    }
}
// 良好設(shè)計(jì):職責(zé)分離
class DownloadTask implements Runnable {
    private String url;
    private String savePath;
    public DownloadTask(String url, String savePath) {
        this.url = url;
        this.savePath = savePath;
    }
    @Override
    public void run() {
        // 僅關(guān)注下載業(yè)務(wù)邏輯
        downloadFile(url, savePath);
    }
    private void downloadFile(String url, String savePath) {
        // 具體的下載實(shí)現(xiàn)
    }
}
// 線程管理與業(yè)務(wù)邏輯分離
Thread downloadThread = new Thread(new DownloadTask("http://example.com/file", "/path/to/save"));
downloadThread.start();

優(yōu)勢:Runnable實(shí)現(xiàn)類專注于任務(wù)邏輯,Thread類專注于線程管理,符合面向?qū)ο笤O(shè)計(jì)原則。

3.3 資源共享:多個(gè)線程可共享同一任務(wù)

// 場景:多個(gè)線程處理同一共享資源
class CounterTask implements Runnable {
    private int count = 0;
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            synchronized (this) {
                count++;
            }
        }
    }
    public int getCount() {
        return count;
    }
}
// 共享同一個(gè)Runnable實(shí)例
CounterTask sharedTask = new CounterTask();
// 多個(gè)線程共享同一任務(wù)對象
Thread thread1 = new Thread(sharedTask, "Thread-1");
Thread thread2 = new Thread(sharedTask, "Thread-2");
Thread thread3 = new Thread(sharedTask, "Thread-3");
thread1.start();
thread2.start();
thread3.start();
// 所有線程執(zhí)行完畢后,共享的count是3000

對比繼承方式

// 如果繼承Thread,每個(gè)線程有自己的count實(shí)例
class CounterThread extends Thread {
    private int count = 0;  // 每個(gè)線程獨(dú)立實(shí)例
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            synchronized (this) {
                count++;
            }
        }
    }
}
// 每個(gè)線程有獨(dú)立的count,無法共享
CounterThread t1 = new CounterThread();
CounterThread t2 = new CounterThread();
// t1和t2的count是獨(dú)立的

優(yōu)勢:Runnable實(shí)例可以輕松在多個(gè)線程間共享,便于實(shí)現(xiàn)資源共享和狀態(tài)同步。

3.4 線程池兼容性:Executor框架的天然適配

import java.util.concurrent.*;
// Runnable與Executor框架完美配合
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交Runnable任務(wù)
executor.submit(new Runnable() {
    @Override
    public void run() {
        System.out.println("任務(wù)執(zhí)行中");
    }
});
// 使用Lambda表達(dá)式簡化(JDK8)
executor.submit(() -> System.out.println("Lambda任務(wù)"));
// 而Thread對象無法直接提交給Executor
// executor.submit(new MyThread()); // 可以但不推薦,因?yàn)門hread也是Runnable
// 問題:Thread的start()方法只能調(diào)用一次,線程池會(huì)重復(fù)調(diào)用run()而非start()

關(guān)鍵問題:Thread對象雖然實(shí)現(xiàn)了Runnable,但其start()方法有特殊邏輯(創(chuàng)建系統(tǒng)線程),直接作為Runnable提交給線程池會(huì)導(dǎo)致問題:

  • 線程池調(diào)用run()而非start()
  • run()方法會(huì)在線程池的工作線程中執(zhí)行,而非創(chuàng)建新線程
  • 違反了Thread的設(shè)計(jì)初衷

3.5 靈活性:組合優(yōu)于繼承

// 使用Runnable可以靈活組合功能
class LoggingRunnable implements Runnable {
    private final Runnable delegate;
    public LoggingRunnable(Runnable delegate) {
        this.delegate = delegate;
    }
    @Override
    public void run() {
        long start = System.currentTimeMillis();
        System.out.println("任務(wù)開始: " + Thread.currentThread().getName());
        delegate.run();  // 委托執(zhí)行實(shí)際任務(wù)
        long end = System.currentTimeMillis();
        System.out.println("任務(wù)結(jié)束,耗時(shí): " + (end - start) + "ms");
    }
}
// 使用裝飾器模式增強(qiáng)功能
Runnable coreTask = () -> {
    // 核心業(yè)務(wù)邏輯
    System.out.println("執(zhí)行核心業(yè)務(wù)");
};
Runnable enhancedTask = new LoggingRunnable(coreTask);
// 執(zhí)行增強(qiáng)后的任務(wù)
Thread thread = new Thread(enhancedTask);
thread.start();
// 輸出:
// 任務(wù)開始: Thread-0
// 執(zhí)行核心業(yè)務(wù)
// 任務(wù)結(jié)束,耗時(shí): Xms

優(yōu)勢:Runnable支持裝飾器模式、策略模式等設(shè)計(jì)模式,提供了極大的靈活性。

3.6 內(nèi)存開銷:更輕量的對象

// Thread對象 vs Runnable對象的內(nèi)存對比
// Thread對象包含:
// 1. 線程棧(默認(rèn)1MB)
// 2. 程序計(jì)數(shù)器
// 3. 本地方法棧
// 4. 線程狀態(tài)、優(yōu)先級(jí)等大量字段
// Runnable實(shí)現(xiàn)類:
// 1. 僅包含業(yè)務(wù)相關(guān)字段
// 2. 通常更輕量
// 場景:需要?jiǎng)?chuàng)建大量任務(wù)時(shí)
List<Thread> threads = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    threads.add(new MyThread());  // 每個(gè)Thread對象約1MB棧內(nèi)存
}
// 總內(nèi)存:~1000MB
List<Runnable> tasks = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
    tasks.add(new MyRunnable());  // 每個(gè)Runnable對象很小
}
// 使用線程池管理,只需少量Thread對象

優(yōu)勢:Runnable對象更輕量,適合大量任務(wù)的場景。

到此這篇關(guān)于JDK8中線程實(shí)現(xiàn)的本質(zhì)與最佳實(shí)踐的文章就介紹到這了,更多相關(guān)jdk8線程實(shí)現(xiàn)本質(zhì)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java URL編碼與解碼基礎(chǔ)詳解

    Java URL編碼與解碼基礎(chǔ)詳解

    這篇文章主要介紹了Java URL編碼與解碼基礎(chǔ)詳解,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • springboot實(shí)現(xiàn)配置本地訪問端口及路徑

    springboot實(shí)現(xiàn)配置本地訪問端口及路徑

    這篇文章主要介紹了springboot實(shí)現(xiàn)配置本地訪問端口及路徑,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • SpringData Repository Bean方法定義規(guī)范代碼實(shí)例

    SpringData Repository Bean方法定義規(guī)范代碼實(shí)例

    這篇文章主要介紹了SpringData Repository Bean方法定義規(guī)范代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Elasticsearch搜索原理及詳細(xì)過程講解

    Elasticsearch搜索原理及詳細(xì)過程講解

    Elasticsearch的搜索原理主要是通過倒排索引實(shí)現(xiàn)的,而倒排索引是相對于像MySQL數(shù)據(jù)庫搜索數(shù)據(jù)的正向索引而言的,這篇文章主要介紹了Elasticsearch搜索原理及詳細(xì)過程的相關(guān)資料,需要的朋友可以參考下
    2025-08-08
  • MyBatis-Plus?中?nested()?與?and()?方法詳解(最佳實(shí)踐場景)

    MyBatis-Plus?中?nested()?與?and()?方法詳解(最佳實(shí)踐場景)

    在MyBatis-Plus的條件構(gòu)造器中,nested()和and()都是用于構(gòu)建復(fù)雜查詢條件的關(guān)鍵方法,但它們在功能和使用場景上有顯著差異,本文給大家介紹MyBatis-Plus中nested()與and()方法,感興趣的朋友一起看看吧
    2025-07-07
  • SpringBoot上傳文件并配置本地資源映射來訪問文件的實(shí)例代碼

    SpringBoot上傳文件并配置本地資源映射來訪問文件的實(shí)例代碼

    這篇文章主要介紹了SpringBoot上傳文件并配置本地資源映射來訪問文件的實(shí)例代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Java ArrayList擴(kuò)容機(jī)制原理深入分析

    Java ArrayList擴(kuò)容機(jī)制原理深入分析

    在Java中,ArrayList是最常用的集合之一。它是一種容器,它的內(nèi)部定義了一個(gè)Object類型的數(shù)組elementData,因此可用于存儲(chǔ)任意類型的數(shù)據(jù)。我們知道,數(shù)組是長度恒定的。而ArrayList相當(dāng)于是一個(gè)長度可變的動(dòng)態(tài)數(shù)組,一起來看看的它的擴(kuò)容機(jī)制
    2023-02-02
  • JAVA 多線程編程之CountDownLatch使用詳解

    JAVA 多線程編程之CountDownLatch使用詳解

    當(dāng)多個(gè)線程需要協(xié)調(diào)和同步執(zhí)行任務(wù)時(shí),Java中的CountDownLatch(倒計(jì)時(shí)門閂)是一個(gè)常用的工具類,本文將介紹 CountDownLatch 的基本原理、用法以及示例代碼,需要的朋友可以參考下
    2023-05-05
  • 解決JDK8的ParallelStream遍歷無序的問題

    解決JDK8的ParallelStream遍歷無序的問題

    這篇文章主要介紹了解決JDK8的ParallelStream遍歷無序的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • Java SSL與TLS客戶端證書配置方式

    Java SSL與TLS客戶端證書配置方式

    這篇文章主要介紹了Java SSL與TLS客戶端證書配置方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論

高阳县| 新乐市| 汤原县| 泰顺县| 大宁县| 略阳县| 望江县| 德阳市| 同江市| 遂宁市| 图木舒克市| 冷水江市| 宁乡县| 嘉义市| 错那县| 呼和浩特市| 庆元县| 柘荣县| 沈丘县| 道真| 集贤县| 安福县| 浦城县| 东丰县| 额济纳旗| 阳城县| 乃东县| 铜鼓县| 阿瓦提县| 锦州市| 垣曲县| 广安市| 太原市| 万源市| 台山市| 巴彦县| 广东省| 贵德县| 明光市| 栾川县| 泾川县|