溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Java中如何實(shí)現(xiàn)異步調(diào)用

發(fā)布時間:2021-07-24 15:44:25 來源:億速云 閱讀:137 作者:Leah 欄目:編程語言

Java中如何實(shí)現(xiàn)異步調(diào)用,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。


@Test
一、創(chuàng)建線程

public void test0() throws Exception {
  System.out.println("main函數(shù)開始執(zhí)行");
  Thread thread=new Thread(new Runnable() {
    @Override
    public void run() {
      System.out.println("===task start===");
      try {
        Thread.sleep(5000);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
      System.out.println("===task finish===");
    }
  });
  thread.start();
  System.out.println("main函數(shù)執(zhí)行結(jié)束");
}

二、Future

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

@Test
public void test1() 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();
}

三、CompletableFuture

使用原生的CompletableFuture實(shí)現(xiàn)異步操作,加上對lambda的支持,可以說實(shí)現(xiàn)異步任務(wù)已經(jīng)發(fā)揮到了極致。

@Test
public void test2() throws Exception {
    System.out.println("main函數(shù)開始執(zhí)行");
    ExecutorService executor = Executors.newFixedThreadPool(2);
    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(new Supplier<Integer>() {
        @Override
        public Integer get() {
            System.out.println("===task start===");
            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("===task finish===");
            return 3;
        }
    }, executor);
    future.thenAccept(e -> System.out.println(e));
    System.out.println("main函數(shù)執(zhí)行結(jié)束");
}

四、Spring的Async注解

使用spring實(shí)現(xiàn)異步需要開啟注解,可以使用xml方式或者Java config的方式。

xml方式:

<task:annotation-driven executor="executor" />
<task:executor id="executor"
        pool-size="2" 線程池的大小
        queue-capacity="100" 排隊(duì)隊(duì)列長度 
        keep-alive="120" 線程?;顣r間(單位秒)
        rejection-policy="CALLER_RUNS" 對拒絕的任務(wù)處理策略 />

java方式:

@EnableAsync
public class MyConfig {
    @Bean
    public TaskExecutor executor(){
        ThreadPoolTaskExecutor executor=new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10); //核心線程數(shù)
        executor.setMaxPoolSize(20);  //最大線程數(shù)
        executor.setQueueCapacity(1000); //隊(duì)列大小
        executor.setKeepAliveSeconds(300); //線程最大空閑時間
        executor.setThreadNamePrefix("fsx-Executor-"); //指定用于新創(chuàng)建的線程名稱的前綴。
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return executor;
    }
}

(1)@Async

@Test
public void test3() throws Exception {
    System.out.println("main函數(shù)開始執(zhí)行");
    myService.longtime();
    System.out.println("main函數(shù)執(zhí)行結(jié)束");
}
 @Async
public void longtime() {
    System.out.println("我在執(zhí)行一項(xiàng)耗時任務(wù)");
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("完成");
}

(2)AsyncResult

如果需要返回值,耗時方法返回值用AsyncResult包裝。

@Test
public void test4() throws Exception {
    System.out.println("main函數(shù)開始執(zhí)行");
    Future future=myService.longtime2();
    System.out.println("main函數(shù)執(zhí)行結(jié)束");
    System.out.println("異步執(zhí)行結(jié)果:"+future.get());
}
 @Async
public Future longtime2() {
    System.out.println("我在執(zhí)行一項(xiàng)耗時任務(wù)");
    try {
        Thread.sleep(8000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    System.out.println("完成");
    return new AsyncResult<>(3);
}

看完上述內(nèi)容,你們掌握J(rèn)ava中如何實(shí)現(xiàn)異步調(diào)用的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI