Java開啟非同步的兩種方式

来源:https://www.cnblogs.com/kakarotto-chen/archive/2023/05/24/17428619.html
-Advertisement-
Play Games

# 二、Java開啟非同步的兩種方式 ## 1、註解開啟:==@Async== ### 1.1、配置非同步的線程池 - 必須配置非同步線程池,否則非同步不會生效。 - @EnableAsync 註解:指定非同步線程池。不指定預設使用:SimpleAsyncTaskExecutor線程池 - SimpleAsy ...


二、Java開啟非同步的兩種方式

1、註解開啟:@Async

1.1、配置非同步的線程池

  • 必須配置非同步線程池,否則非同步不會生效。
  • @EnableAsync 註解:指定非同步線程池。不指定預設使用:SimpleAsyncTaskExecutor線程池
  • SimpleAsyncTaskExecutor是一個最簡單的線程池,它沒有任何的線程相關參數配置,它會為每個任務創建一個新的線程來執行,因此不建議在生產環境中使用。
  • 配置線程池見:https://www.cnblogs.com/kakarotto-chen/p/17428432.html
package com.cc.md.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.ThreadPoolExecutor;

/** IO型的線程池
 * @author CC
 * @since 2023/5/23 0023
 */
@Configuration
@EnableAsync
public class IoThreadPool {

    public static final int THREAD_SIZE = 2 * (Runtime.getRuntime().availableProcessors());
    
    public static final int QUEUE_SIZE = 1000;

    @Bean(name = "myIoThreadPool")
    public ThreadPoolTaskExecutor threadPoolExecutor(){
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(THREAD_SIZE);
        executor.setMaxPoolSize(THREAD_SIZE);
        executor.setQueueCapacity(QUEUE_SIZE);
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        executor.setKeepAliveSeconds(60);
        executor.setAllowCoreThreadTimeOut(true);
        executor.setAwaitTerminationSeconds(300);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setThreadNamePrefix("myIo-Th-Pool-");
        executor.initialize();
        return executor;
    }
}

1.2、非同步方法

  • 非同步方法必須寫在另一個類中,否則不生效
  • @Async可以打在類上、也可以打在方法上
    1 @Async:類上,說明整個類中的方法都是非同步。必須寫我們自己配置的線程池 —— ("myIoThreadPool")
    2 @Async:方法上,說明這個方法是非同步。不用寫我們自己配置的線程池
  • 非同步介面+實現類

介面

package com.cc.md.service;

/**
 * @author CC
 * @since 2023/5/24 0024
 */
public interface IAsyncService {

    /** 非同步方法1
     * @since 2023/5/24 0024
     * @author CC
     **/
    void async1();

    /** 非同步方法2
     * @since 2023/5/24 0024
     * @author CC
     **/
    void async2();

}

實現類

package com.cc.md.service.impl;

import com.cc.md.service.IAsyncService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

/** 1 @Async:類上,說明整個類中的方法都是非同步。必須寫我們自己配置的線程池 —— ("myIoThreadPool")
 *  2 @Async:方法上,說明這個方法是非同步。不用寫我們自己配置的線程池
 * @author CC
 * @since 2023/5/24 0024
 */
@Service
@Async("myIoThreadPool")
public class AsyncServiceImpl implements IAsyncService {

    private static final Logger log = LoggerFactory.getLogger(AsyncServiceImpl.class);

    //類上寫了@Async,這裡就可以不寫了。
    //可以不寫 ("myIoThreadPool")。因為在IoThreadPool中開啟了非同步,說明非同步用的就是我們配置的io線程池
    //如果類上面打了 @Async ,這裡必須寫:("myIoThreadPool")
    @Override
    //@Async
    public void async1(){
        //模仿io流耗時
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("列印:{}", "非同步方法1111!");
    }

    //@Async在類上面,說明這個方法也是非同步方法。如果不打,無法開啟非同步。
    @Override
    public void async2(){
        //模仿io流耗時
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("列印:{}", "非同步方法2222!");
    }
}

1.3、測試

    @Resource
    private IAsyncService asyncService;
    
    //開啟非同步1 —— @Async
    @Test
    public void test03() throws Exception {
        log.info("列印:{}", "非同步測試的-主方法1");
        asyncService.async1();
        asyncService.async2();
        //不會等待非同步方法執行,直接返回前端數據
        log.info("列印:{}", "非同步測試的-主方法2");
    }

結果:

image

2、CompletableFuture的方式

使用:

    @Resource(name = "myIoThreadPool")
    private ThreadPoolTaskExecutor myIoThreadPool;
    
    //開啟非同步2 —— CompletableFuture.runAsync()
    @Test
    public void test04() throws Exception {
        log.info("列印:{}", "非同步測試的-主方法1");
        CompletableFuture.runAsync(() -> {
            log.info("列印:{}", "非同步方法1!");
            //非同步執行的代碼,也可以是方法,該方法不用單獨寫到其他類中。
            this.async2("非同步方法1!-end");
        }, myIoThreadPool);
        //不會等待非同步方法執行,直接返回前端數據
        log.info("列印:{}", "非同步測試的-主方法2");
    }

    //非同步需要執行的方法,可以寫在同一個類中。
    private void async2(String msg) {
        //模仿io流耗時
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        log.info("列印:{}", msg);
    }

結果:

image

  • 後續CompletableFuture的使用見:《Java的CompletableFuture,Java的多線程開發》

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、什麼是微服務 微服務是一種技術架構,通常我們可以把它理解為一組可以相互之間協同工作的應用程式或服務,這些應用程式或服務能夠被單獨部署到不同的伺服器中,並且能夠自主運行和維護。 微服務技術只是一個名稱而已,或許我們在日常工作中已經或多或少在使用其中的一種或幾種技術和架構,但我們並沒有將其稱之為微服 ...
  • 汽車之家電商系統誕生在2014年,成長於2016~2019年,並經歷多年雙11、818晚會的洪峰考驗,沉澱了穩定可靠、性能卓越的線上交易能力。隨著業務中台的建設浪潮興起,2019年進入中台化建設階段,輸出其在汽車電商領域五年沉澱的能力,助力汽車電商行業發展,加速企業數字化轉型! ...
  • ## 初步瞭解 ### 總體架構設計 Mybatis 整體框架如下: ![img](https://zhangjiahao-blog.oss-cn-beijing.aliyuncs.com/picgo/202305161021323.png) ##### 介面層 MyBatis 和資料庫的交互有兩種 ...
  • # Java語法基礎 ## 註釋 註釋是對代碼的解釋和說明文字,可以提高程式的可讀性,因此在程式中添加必要的註釋文字十分重要。Java中的註釋分為三種: 單行註釋。單行註釋的格式是使用//,從//開始至本行結尾的文字將作為註釋文字。 ~~~java // 這是單行註釋文字 ~~~ 多行註釋。多行註釋 ...
  • ## 教程簡介 Apache Kafka由Scala寫成。Kafka最初是由LinkedIn開發,並於2011年初開源。2012年10月從Apache Incubator畢業。該項目的目標是為處理實時數據提供一個統一、高通量、低等待的平臺。 Kafka是一個分散式的、分區的、多複本的日誌提交服務。它 ...
  • 最近在壓測一批介面,發現介面處理速度慢的有點超出預期,感覺很奇怪,後面定位發現是資料庫批量保存這塊很慢。 這個項目用的是 mybatis-plus,批量保存直接用的是 mybatis-plus 提供的 saveBatch。 我點進去看了下源碼,感覺有點不太對勁: 繼續追蹤了下,從這個代碼來看,確實是 ...
  • # 圖紙管理系統 ## 一、初步構建後端項目 ### 1、打開已經創建好的虛擬環境:激活activate(推薦使用虛擬環境)並創建項目 ![](https://img2023.cnblogs.com/blog/2240937/202305/2240937-20230524164953360-1300 ...
  • ### StringIO和BytesIO 很多時候,數據讀寫不一定是文件,也可以在記憶體中讀寫。StringIO就是在記憶體中讀寫str。 要把str寫入StringIO,我們需要先創建一個StringIO,然後,像文件一樣寫入即可: ```python >>> from io import Strin ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...