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

Java異步編程的5種異步實現(xiàn)方式詳解

 更新時間:2024年01月22日 09:11:52   作者:我不是歐拉_  
這篇文章主要介紹了Java異步編程的5種異步實現(xiàn)方式詳解,異步編程是程序并發(fā)運行的一種手段,它允許多個事件同時發(fā)生,當(dāng)程序調(diào)用需要長時間運行的方法時,它不會阻塞當(dāng)前的執(zhí)行流程,程序可以繼續(xù)運行,需要的朋友可以參考下

1. 什么是異步?

首先我們先來看看一個同步的用戶注冊例子,流程如下:

在同步操作中,我們執(zhí)行到插入數(shù)據(jù)庫的時候,我們必須等待這個方法徹底執(zhí)行完才能執(zhí)行“發(fā)送短信”這個操作,如果插入數(shù)據(jù)庫這個動作執(zhí)行時間較長,發(fā)送短信需要等待,這就是典型的同步場景。

于是聰明的人們開始思考,如果兩者關(guān)聯(lián)性不強,能不能將一些非核心業(yè)務(wù)從主流程中剝離出來,于是有了異步編程雛形,改進后的流程如下:

這就是異步編程,它是程序并發(fā)運行的一種手段,它允許多個事件同時發(fā)生,當(dāng)程序調(diào)用需要長時間運行的方法時,它不會阻塞當(dāng)前的執(zhí)行流程,程序可以繼續(xù)運行。

在聊完異步編程后,那么我們一起來看看Java里面實現(xiàn)異步編程究竟有哪些方式呢?

2. 線程異步

在 Java 語言中最簡單使用異步編程的方式就是創(chuàng)建一個 線程來實現(xiàn),如果你使用的 JDK 版本是 8 以上的話,可以使用 Lambda 表達式 會更加簡潔。

public class AsyncThread extends Thread{
    @Override
    public void run() {
        System.out.println("當(dāng)前線程名稱:" + this.getName() + ", 執(zhí)行線程名稱:" + Thread.currentThread().getName() + "-hello");
    }
}
public static void main(String[] args) {
  // 模擬業(yè)務(wù)流程
  // .......
    // 創(chuàng)建異步線程 
    AsyncThread asyncThread = new AsyncThread();
    // 啟動異步線程
    asyncThread.start();
}

當(dāng)然如果每次都創(chuàng)建一個 Thread線程,頻繁的創(chuàng)建、銷毀,浪費系統(tǒng)資源,我們可以采用線程池:

private ExecutorService executor = Executors.newCachedThreadPool() ;
    public void fun() throws Exception {
        executor.submit(new Runnable(){
                @override
                public void run() {
                    try {
                     // 要執(zhí)行的業(yè)務(wù)代碼,我們這里沒有寫方法,可以讓線程休息幾秒進行測試
                        Thread.sleep(10000);
                        System.out.print("睡夠啦~");
                    }catch(Exception e) {
                        throw new RuntimeException("報錯啦??!");
                    }
                }
        });
    }

將業(yè)務(wù)邏輯封裝到 Runnable 或 Callable 中,交由 線程池 來執(zhí)行 

3. Future異步

上述方式雖然達到了多線程并行處理,但有些業(yè)務(wù)不僅僅要執(zhí)行過程,還要獲取執(zhí)行結(jié)果,后續(xù)提供在JUC包增加了Future。

從字面意思理解就是未來的意思,但使用起來卻著實有點雞肋,并不能實現(xiàn)真正意義上的異步,獲取結(jié)果時需要阻塞線程,或者不斷輪詢。

@Test
public void futureTest() throws Exception {
    System.out.println("main函數(shù)開始執(zhí)行");
    ExecutorService executor = Executors.newFixedThreadPool(1);
    Future<Integer> future = executor.submit(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            System.out.println("===task start===");
            Thread.sleep(5000);
            System.out.println("===task finish===");
            return 3;
        }
    });
    // 這里需要返回值時會阻塞主線程,如果不需要返回值使用是OK的。倒也還能接受
    // Integer result=future.get();
    System.out.println("main函數(shù)執(zhí)行結(jié)束");
    System.in.read();
}

4. CompletableFuture異步

Future 類通過 get() 方法阻塞等待獲取異步執(zhí)行的運行結(jié)果,性能比較差。

JDK1.8 中,Java 提供了 CompletableFuture 類,它是基于異步函數(shù)式編程。相對阻塞式等待返回結(jié)果,CompletableFuture 可以通過回調(diào)的方式來處理計算結(jié)果,實現(xiàn)了異步非阻塞,性能更優(yōu)。

CompletableFuture 實現(xiàn)了 Future 和 CompletionStage 接口, 并提供了多種實現(xiàn)異步編程的方法,如supplyAsync, runAsync以及thenApplyAsync。

下面我們使用CompletableFuture來實現(xiàn)上面的例子:

CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> factorial(number));
while (!completableFuture.isDone()) {
    System.out.println("CompletableFuture is not finished yet...");
}
long result = completableFuture.get();

我們不需要顯式使用 ExecutorService,CompletableFuture 內(nèi)部使用了 ForkJoinPool 來處理異步任務(wù),這使得我們的代碼變的更簡潔。

5. SpringBoot @Async異步

在@Async注解之前,使用多線程需要使用JDK的原生方法,非常麻煩,當(dāng)有了@Async之后就比較簡單了。

首先,使用 @EnableAsync 啟用異步注解:

@SpringBootApplication
@EnableAsync
public class StartApplication {
    public static void main(String[] args) {
        SpringApplication.run(StartApplication.class, args);
    }
}
// 自定義線程池:
@Configuration
@Slf4j
public class ThreadPoolConfiguration {
    @Bean(name = "defaultThreadPoolExecutor", destroyMethod = "shutdown")
    public ThreadPoolExecutor systemCheckPoolExecutorService() {
        return new ThreadPoolExecutor(3, 10, 60, TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(10000),
                new ThreadFactoryBuilder().setNameFormat("default-executor-%d").build(),
                (r, executor) -> log.error("system pool is full! "));
    }
}
// 在異步處理的方法上添加注解 @Async ,當(dāng)對 execute 方法 調(diào)用時,通過自定義的線程池 defaultThreadPoolExecutor 異步化執(zhí)行  execute 方法
@Service
public class AsyncServiceImpl implements AsyncService {
    @Async("defaultThreadPoolExecutor")
    public Boolean execute(Integer num) {
        System.out.println("線程:" + Thread.currentThread().getName() + " , 任務(wù):" + num);
        return true;
    }
}

用 @Async 注解標(biāo)記的方法,稱為異步方法。在spring boot應(yīng)用中使用 @Async 很簡單:

  • 調(diào)用異步方法類上或者啟動類加上注解 @EnableAsync
  • 在需要被異步調(diào)用的方法外加上 @Async
  • 所使用的 @Async 注解方法的類對象應(yīng)該是Spring容器管理的bean對象;

6. Guava異步

Guava 提供了 ListenableFuture 類來執(zhí)行異步操作

1. 首先我們需要添加 guava 的maven依賴:

<dependency>
    <groupId>com.google.guava</groupId>
    <artifactId>guava</artifactId>
    <version>28.2-jre</version>
</dependency>

2. 現(xiàn)在我們使用ListenableFuture來實現(xiàn)我們之前的例子:

ExecutorService threadpool = Executors.newCachedThreadPool();
ListeningExecutorService service = MoreExecutors.listeningDecorator(threadpool);
ListenableFuture<Long> guavaFuture = (ListenableFuture<Long>) service.submit(()-> factorial(number));
long result = guavaFuture.get();

這里使用MoreExecutors獲取ListeningExecutorService類的實例,然后ListeningExecutorService.submit執(zhí)行異步任務(wù),并返回 ListenableFuture實例。

到此這篇關(guān)于Java異步編程的5種異步實現(xiàn)方式詳解的文章就介紹到這了,更多相關(guān)Java異步編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java 動態(tài)生成bean的案例

    java 動態(tài)生成bean的案例

    這篇文章主要介紹了java 動態(tài)生成bean的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • Spring security自定義用戶認證流程詳解

    Spring security自定義用戶認證流程詳解

    這篇文章主要介紹了Spring security自定義用戶認證流程詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-03-03
  • Java算法之快速排序舉例詳解

    Java算法之快速排序舉例詳解

    這篇文章主要介紹了Java算法之快速排序的相關(guān)資料,快速排序是一種高效的排序算法,通過遞歸的方式將待排序數(shù)組分成小部分進行排序,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2025-04-04
  • Java下SpringBoot創(chuàng)建定時任務(wù)詳解

    Java下SpringBoot創(chuàng)建定時任務(wù)詳解

    這篇文章主要介紹了Java下SpringBoot創(chuàng)建定時任務(wù)詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 基于java線程安全問題及原理性分析

    基于java線程安全問題及原理性分析

    下面小編就為大家?guī)硪黄趈ava線程安全問題及原理性分析。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-07-07
  • springboot整合Sa-Token實現(xiàn)登錄認證和權(quán)限校驗的詳細流程

    springboot整合Sa-Token實現(xiàn)登錄認證和權(quán)限校驗的詳細流程

    Sa-Token是國產(chǎn)輕量級權(quán)限認證框架,支持登錄、權(quán)限校驗、單點登錄及分布式會話,配置簡便且API設(shè)計直觀,相比Spring Security更易上手,適合快速實現(xiàn)安全功能,助力國產(chǎn)開源發(fā)展,感興趣的朋友跟隨小編一起看看吧
    2025-09-09
  • 詳解Java數(shù)組的定義和聲明方法

    詳解Java數(shù)組的定義和聲明方法

    在Java開發(fā)中,數(shù)組是最常用的數(shù)據(jù)結(jié)構(gòu)之一,因此,深入了解Java數(shù)組的定義和聲明是非常必要的,本文將詳細介紹Java數(shù)組的定義和聲明方法,以及其在實際開發(fā)中的應(yīng)用場景、優(yōu)缺點等方面,需要的朋友可以參考下
    2023-11-11
  • Spring實現(xiàn)定時任務(wù)的幾種方式總結(jié)

    Spring實現(xiàn)定時任務(wù)的幾種方式總結(jié)

    Spring Task 是 Spring 框架提供的一種任務(wù)調(diào)度和異步處理的解決方案,可以按照約定的時間自動執(zhí)行某個代碼邏輯它可以幫助開發(fā)者在 Spring 應(yīng)用中輕松地實現(xiàn)定時任務(wù)、異步任務(wù)等功能,提高應(yīng)用的效率和可維護性,需要的朋友可以參考下本文
    2024-07-07
  • Mybatis使用update更新值為null時不生效問題解決

    Mybatis使用update更新值為null時不生效問題解決

    這篇文章主要介紹了Mybatis使用update更新值為null時不生效問題解決,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • java安全停止線程的方法詳解

    java安全停止線程的方法詳解

    這篇文章主要介紹了java安全停止線程的方法詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-10-10

最新評論

金塔县| 绿春县| 丹巴县| 鹰潭市| 库伦旗| 丰县| 自贡市| 闵行区| 泰安市| 延庆县| 巴马| 邵阳县| 绥宁县| 南陵县| 灌阳县| 陇川县| 呼图壁县| 宜春市| 瓦房店市| 垣曲县| 肇东市| 乐都县| 太保市| 中西区| 平阴县| 平湖市| 逊克县| 永平县| 沙洋县| 阳信县| 吉水县| 巨鹿县| 冷水江市| 台东县| 静宁县| 炉霍县| 万荣县| 福州市| 阿荣旗| 石台县| 大埔县|