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

Java中5種異步實(shí)現(xiàn)的方式詳解

 更新時(shí)間:2022年09月19日 10:17:35   作者:mikechen的互聯(lián)網(wǎng)架構(gòu)  
同步操作如果遇到一個(gè)耗時(shí)的方法,需要阻塞等待,那么我們有沒有辦法解決呢?讓它異步執(zhí)行,下面我會(huì)詳解異步及實(shí)現(xiàn),需要的可以參考一下

一、什么是異步

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

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

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

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

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

二、線程異步

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

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();

    // 啟動(dòng)異步線程
    asyncThread.start();
}

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

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

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

三、Future異步

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

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

@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;
        }
    });
    //這里需要返回值時(shí)會(huì)阻塞主線程,如果不需要返回值使用是OK的。倒也還能接收
    //Integer result=future.get();
    System.out.println("main函數(shù)執(zhí)行結(jié)束");

    System.in.read();

}

四、CompletableFuture異步

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

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

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

下面我們使用CompletableFuture來實(shí)現(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ù),這使得我們的代碼變的更簡(jiǎn)潔。

五、SpringBoot @Async異步

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

首先,使用 @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)對(duì) execute 方法 調(diào)用時(shí),通過自定義的線程池 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 很簡(jiǎn)單:

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

六、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來實(shí)現(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類的實(shí)例,然后ListeningExecutorService.submit執(zhí)行異步任務(wù),并返回 ListenableFuture實(shí)例。

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

相關(guān)文章

  • 基于ThreadLocal 的用法及內(nèi)存泄露(內(nèi)存溢出)

    基于ThreadLocal 的用法及內(nèi)存泄露(內(nèi)存溢出)

    這篇文章主要介紹了基于ThreadLocal 的用法及內(nèi)存泄露(內(nèi)存溢出),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java使用反射獲取字段屬性

    Java使用反射獲取字段屬性

    這篇文章主要為大家詳細(xì)介紹了Java如何利用反射實(shí)現(xiàn)獲取字段屬性值,文中的示例代碼講解詳細(xì),具有很好的參考價(jià)值,希望對(duì)大家有所幫助
    2023-06-06
  • Reactive Programming入門概念詳解

    Reactive Programming入門概念詳解

    這篇文章主要為大家介紹了Reactive Programming入門概念詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-09-09
  • Java的Spring框架中bean的繼承與內(nèi)部bean的注入

    Java的Spring框架中bean的繼承與內(nèi)部bean的注入

    這篇文章主要介紹了Java的Spring框架中bean的繼承與內(nèi)部bean的注入,Spring框架是Java的SSH三大web開發(fā)框架之一,需要的朋友可以參考下
    2015-12-12
  • 使用SpringJPA?直接實(shí)現(xiàn)count(*)

    使用SpringJPA?直接實(shí)現(xiàn)count(*)

    這篇文章主要介紹了SpringJPA?直接實(shí)現(xiàn)count(*),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringBoot如何打印mybatis的執(zhí)行sql問題

    SpringBoot如何打印mybatis的執(zhí)行sql問題

    這篇文章主要介紹了SpringBoot如何打印mybatis的執(zhí)行sql問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • 關(guān)于Springboot2.x集成lettuce連接redis集群報(bào)超時(shí)異常Command timed out after 6 second(s)

    關(guān)于Springboot2.x集成lettuce連接redis集群報(bào)超時(shí)異常Command timed out afte

    這篇文章主要介紹了Springboot2.x集成lettuce連接redis集群報(bào)超時(shí)異常Command timed out after 6 second(s),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2021-03-03
  • SpringBoot框架如何操作Excel和PDF

    SpringBoot框架如何操作Excel和PDF

    Excel和PDF都是常見的辦公文件類型,在實(shí)際需求中有著較多的應(yīng)用,excel經(jīng)常用來處理數(shù)據(jù),PDF文件格式可以將文字、字型、格式、顏色及獨(dú)立于設(shè)備和分辨率的圖形圖像等封裝在一個(gè)文件中,本文就講述下SpringBoot框架如何操作這兩種類型的文件
    2021-06-06
  • java加解密RSA使用方法代碼示例

    java加解密RSA使用方法代碼示例

    這篇文章主要介紹了java加解密RSA使用方法代碼示例,還是比較不錯(cuò)的,這里分享給大家,供需要的朋友參考。
    2017-10-10
  • Java中IO流的BufferedOutputStream和FileOutputStream對(duì)比

    Java中IO流的BufferedOutputStream和FileOutputStream對(duì)比

    這篇文章主要介紹了Java中IO流的BufferedOutputStream和FileOutputStream對(duì)比,不帶緩沖的操作,每讀一個(gè)字節(jié)就要寫入一個(gè)字節(jié),由于涉及磁盤的IO操作相比內(nèi)存的操作要慢很多,所以在讀寫的字節(jié)比較少的情況下,效率比較低,需要的朋友可以參考下
    2023-07-07

最新評(píng)論

会宁县| 台东市| 鸡东县| 凤阳县| 马公市| 房产| 卢湾区| 华蓥市| 虹口区| 阿瓦提县| 文登市| 隆德县| 唐山市| 丰顺县| 延长县| 吉隆县| 绍兴市| 武安市| 庄浪县| 林芝县| 高要市| 黑水县| 乌拉特中旗| 郯城县| 土默特右旗| 房产| 崇左市| 安陆市| 甘孜县| 东光县| 三原县| 桓台县| 涞源县| 镇康县| 孙吴县| 体育| 崇信县| 淮南市| 宁远县| 古田县| 潮安县|