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

Java線程池中execute()和submit()的區(qū)別全解析(源碼&實戰(zhàn))

 更新時間:2026年02月07日 11:45:00   作者:Knight_AL  
這篇文章主要介紹了Java線程池中execute()和submit()區(qū)別的相關(guān)資料,它們之間的主要區(qū)別在于submit方法可以返回結(jié)果、捕獲異常、支持任務(wù)取消和批量匯總結(jié)果,而execute方法則不關(guān)心返回值,異常會直接拋出,需要的朋友可以參考下

前言

在 Java 并發(fā)編程里, ThreadPoolExecutor 是最常用的組件之一,而其中最常用的兩個方法就是:

execute(Runnable command)
submit(Callable/Runnable task)

看起來只有“是否有返回值”的差別?

其實遠(yuǎn)不止如此!

一、簡單對比:一張表記住核心差異

項目execute()submit()
所屬接口ExecutorExecutorService
接受參數(shù)RunnableRunnable / Callable
是否有返回值? 無? Future,可取消,可拿結(jié)果
異常處理?異常直接拋出到線程的 UncaughtExceptionHandler?? 異常被捕獲放進(jìn) Future(不會直接打印)
是否可取消? 無? 可用 Future.cancel()
是否支持批量匯總結(jié)果? 不支持? 支持 Future + CompletionService

一句話總結(jié):

execute 用來“執(zhí)行任務(wù)”, submit 用來“管理任務(wù)”。

二、execute():輕量級任務(wù)執(zhí)行,不關(guān)心結(jié)果

executor.execute(() -> {
    System.out.println("logging...");
    int x = 1 / 0;  // 會打印異常棧
});

特點:

  • 不關(guān)心返回值
  • 異常會直接拋到控制臺
  • 性能開銷更?。ú粍?chuàng)建 FutureTask)

適用場景:

  • 記錄訪問日志
  • 異步發(fā) MQ、埋點
  • 刷緩存、通知等“扔過去就不管了”的任務(wù)

三、submit():帶狀態(tài)的任務(wù)管理,有返回值,可捕獲異常

Future<Integer> future = executor.submit(() -> {
    return 123;
});
System.out.println(future.get()); // 結(jié)果 123

submit 最大的隱形區(qū)別:異常不會自動拋出

Future<?> f = executor.submit(() -> {
    throw new RuntimeException("error");
});

f.get(); // ExecutionException:異常從這里拋出

為什么?

因為 submit 內(nèi)部把任務(wù)包成了 FutureTask,它會:

try {
    call()
} catch (Throwable t) {
    setException(t);  // 保存到 Future
}

→ 所以異常不會直接爆出來,而是等你 future.get() 再拋。

四、源碼視角:submit 底層其實也是調(diào)用 execute

submit 并不是獨立執(zhí)行任務(wù),它是:

  1. 把 Runnable/Callable 包裝成 FutureTask
  2. 調(diào)用 execute 執(zhí)行 FutureTask

源碼(摘自 AbstractExecutorService):

public <T> Future<T> submit(Callable<T> task) {
    RunnableFuture<T> f = newTaskFor(task);
    execute(f);  // 注意這里!
    return f;
}

而 execute 是線程池真正調(diào)度任務(wù)的入口。

五、異常處理的根本差別(重點?。?/h2>
方法任務(wù)內(nèi)部拋異常會怎樣?
execute異常會冒泡到線程頂層 → 默認(rèn)打印棧追蹤
submit異常被 FutureTask 捕獲 → 不會打印,需要 future.get() 才能感知到

示例:submit 吃掉異常

executor.submit(() -> {
    throw new RuntimeException("Boom!");
});

// 控制臺不會輸出任何異常

如果你不 get(),異常就徹底靜悄悄消失了,這在真實項目里非常危險。

“為什么 submit() 會吃掉異常?怎么處理?”

答案:用 get() 捕獲 ExecutionException,從 cause 拿真正異常。

六、真實業(yè)務(wù)場景如何選擇?

? execute() 適用于:

  • 不需要返回值
  • 不需要任務(wù)取消
  • 不關(guān)心任務(wù)是否失敗

典型業(yè)務(wù):

  • 訪問日志
  • 埋點
  • 異步通知
  • 緩存刷新

? submit() 適用于:

  • 需要匯總結(jié)果(并發(fā)調(diào)用多個服務(wù))
  • 需要捕獲異常
  • 需要任務(wù)狀態(tài)(是否完成、是否失?。?/li>
  • 需要 cancel

典型業(yè)務(wù)(例如醫(yī)療系統(tǒng)):

  • 藥審 + 過敏 + 醫(yī)保試算:并發(fā)執(zhí)行,返回綜合結(jié)果
  • 大報表導(dǎo)出:后臺執(zhí)行 + 查詢狀態(tài) + 可取消
  • 風(fēng)險評估:多線程計算指標(biāo)后統(tǒng)一合并
  • 第三方接口調(diào)用:需要捕獲異常、重試、降級

七、一個真實示例:醫(yī)療系統(tǒng)并發(fā)校驗醫(yī)囑

Future<DrugAuditResult> drugF = pool.submit(() -> drugAudit());
Future<AllergyResult> allergyF = pool.submit(() -> checkAllergy());
Future<InsuranceResult> insF = pool.submit(() -> preCalcInsurance());

try {
    DrugAuditResult d = drugF.get();
    AllergyResult a = allergyF.get();
    InsuranceResult i = insF.get();
    return new Summary(d, a, i);
} catch (ExecutionException e) {
    log.error("校驗失敗", e.getCause());
    throw new BusinessException("醫(yī)囑校驗失敗");
}

這里必須用 submit,因為你要:

  • 拿返回值
  • 捕獲異常
  • 匯總結(jié)果

八、最終總結(jié)

execute 和 submit 的本質(zhì)區(qū)別:

關(guān)鍵點executesubmit
是否包裝 Future?? 否? 是
異常如何處理?直接拋出存 Future 內(nèi),get 時拋
是否有返回值?
是否可取消?
是否適合任務(wù)編排/匯總結(jié)果???

execute 用來“執(zhí)行任務(wù)”, submit 用來“管理任務(wù)”。

到此這篇關(guān)于Java線程池中execute()和submit()區(qū)別的文章就介紹到這了,更多相關(guān)Java線程池execute()和submit()內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 嵌套類的詳解及實例代碼

    java 嵌套類的詳解及實例代碼

    這篇文章主要介紹了java 嵌套類的詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • Swing常用組件之單選按鈕和復(fù)選框

    Swing常用組件之單選按鈕和復(fù)選框

    Swing是一個用于開發(fā)Java應(yīng)用程序用戶界面的開發(fā)工具包,這篇文章主要介紹了Swing常用組件之單選按鈕和復(fù)選框,感興趣的朋友可以參考一下
    2016-05-05
  • Spring Boot4使用Sentinel進(jìn)行限流的操作方法

    Spring Boot4使用Sentinel進(jìn)行限流的操作方法

    Sentinel是阿里巴巴開源的流量控制組件,用于保障微服務(wù)架構(gòu)的穩(wěn)定性,它提供了多種規(guī)則類型,本文還介紹了如何在Spring Boot 4中集成Sentinel,以及Sentinel在不同版本的Spring Boot和Spring Cloud中的兼容性情況,感興趣的朋友跟隨小編一起看看吧
    2025-12-12
  • Java將文件內(nèi)容讀取為字符串的實現(xiàn)步驟

    Java將文件內(nèi)容讀取為字符串的實現(xiàn)步驟

    在Java編程中,經(jīng)常需要將文件內(nèi)容讀取為字符串進(jìn)行處理,比如配置文件讀取、文本數(shù)據(jù)解析等場景,不同版本的Java提供了多種實現(xiàn)方式,同時也有一些外部庫可以簡化操作,本文給大家介紹了Java將文件內(nèi)容讀取為字符串的實現(xiàn)步驟,需要的朋友可以參考下
    2025-06-06
  • 深入了解MyBatis分頁機(jī)制

    深入了解MyBatis分頁機(jī)制

    在企業(yè)項目的數(shù)據(jù)庫操作中,分頁查詢是一個常見需求,尤其當(dāng)數(shù)據(jù)量龐大時,MyBatis作為我們Java開發(fā)者的持久層框架,為分頁提供了靈活的支持,本篇文章我們將深入探討MyBatis的分頁機(jī)制,使我們在實際開發(fā)項目中運用自如,需要的朋友可以參考下
    2023-12-12
  • Java線程中的Timer和TimerTask原理詳解

    Java線程中的Timer和TimerTask原理詳解

    這篇文章主要介紹了Java線程中的Timer和TimerTask原理詳解,Timer和TimerTask成對出現(xiàn),Timer是定時器,TimerTask是定時任務(wù),換句話說,定時任務(wù)TimerTask是給定時器Timer執(zhí)行的具體任務(wù),需要的朋友可以參考下
    2023-10-10
  • 詳解Java中兩種分頁遍歷的使用姿勢

    詳解Java中兩種分頁遍歷的使用姿勢

    這篇文章主要介紹了詳解Java中兩種分頁遍歷的使用姿勢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Java中序列化和反序列化的完整講解

    Java中序列化和反序列化的完整講解

    序列化是將對象轉(zhuǎn)換成二進(jìn)制字節(jié)流的過程;反序列化是從二進(jìn)制字節(jié)流中恢復(fù)對象的過程。文中將為大家詳細(xì)講講二者的原理與實現(xiàn),需要的可以參考一下
    2022-11-11
  • SimpleDateFormat在多線程下的安全問題及解決

    SimpleDateFormat在多線程下的安全問題及解決

    SimpleDateFormat類在Java中用于日期時間的格式化和解析,但在高并發(fā)環(huán)境下存在線程不安全的問題,原因是它共享了一個Calendar對象,導(dǎo)致多個線程操作時出現(xiàn)沖突,為了解決這個問題,可以使用局部變量、加鎖或使用線程安全的DateTimeFormatter類
    2026-03-03
  • SpringBoot3-yaml文件配置方式

    SpringBoot3-yaml文件配置方式

    這篇文章主要介紹了SpringBoot3-yaml文件配置方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-03-03

最新評論

建始县| 买车| 柳林县| 凤山市| 霍山县| 宜州市| 合肥市| 盘山县| 井陉县| 西畴县| 吉木乃县| 白水县| 太康县| 平邑县| 黄浦区| 义乌市| 门头沟区| 眉山市| 淮阳县| 诸城市| 沅陵县| 博野县| 荣昌县| 岢岚县| 洛阳市| 肃宁县| 平顶山市| 黄山市| 清新县| 蒙城县| 安陆市| 全南县| 哈密市| 长乐市| 筠连县| 潜江市| 奉化市| 六盘水市| 布尔津县| 河间市| 朝阳区|