成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

springboot異步調(diào)用@Async

gityuan / 1093人閱讀

摘要:異步處理方式調(diào)用之后,不返回任何數(shù)據(jù)。在有返回值的異步調(diào)用中,異步處理拋出異常,會(huì)直接拋出異常,異步任務(wù)結(jié)束,原有處理結(jié)束執(zhí)行。

1.使用背景

在項(xiàng)目中,當(dāng)訪問其他人的接口較慢或者做耗時(shí)任務(wù)時(shí),不想程序一直卡在耗時(shí)任務(wù)上,想程序能夠并行執(zhí)行,我們可以使用多線程來并行的處理任務(wù),也可以使用spring提供的異步處理方式@Async。

2.異步處理方式

調(diào)用之后,不返回任何數(shù)據(jù)。

調(diào)用之后,返回?cái)?shù)據(jù),通過Future來獲取返回?cái)?shù)據(jù)

3.@Async不返回?cái)?shù)據(jù)

使用@EnableAsync啟用異步注解

@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig{
}

在異步處理的方法dealNoReturnTask上添加注解@Async

@Component
@Slf4j
public class AsyncTask {

    @Async
    public void dealNoReturnTask(){
        log.info("Thread {} deal No Return Task start", Thread.currentThread().getName());
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("Thread {} deal No Return Task end at {}", Thread.currentThread().getName(), System.currentTimeMillis());
    }
}

Test測(cè)試類:

@SpringBootTest(classes = SpringbootApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
@Slf4j
public class AsyncTest {

    @Autowired
    private AsyncTask asyncTask;

    @Test
    public void testDealNoReturnTask(){
        asyncTask.dealNoReturnTask();
        try {
            log.info("begin to deal other Task!");
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

日志打印結(jié)果為:

begin to deal other Task!
AsyncExecutorThread-1 deal No Return Task start
AsyncExecutorThread-1 deal No Return Task end at 1499751227034

從日志中我們可以看出,方法dealNoReturnTask()是異步執(zhí)行完成的。
dealNoReturnTask()設(shè)置sleep 3s是為了模擬耗時(shí)任務(wù)
testDealNoReturnTask()設(shè)置sleep 10s是為了確認(rèn)異步是否執(zhí)行完成

4.@Async返回?cái)?shù)據(jù)

異步調(diào)用返回?cái)?shù)據(jù),F(xiàn)uture表示在未來某個(gè)點(diǎn)獲取執(zhí)行結(jié)果,返回?cái)?shù)據(jù)類型可以自定義

    @Async
    public Future dealHaveReturnTask() {
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("thread", Thread.currentThread().getName());
        jsonObject.put("time", System.currentTimeMillis());
        return new AsyncResult(jsonObject.toJSONString());
    }

測(cè)試類用isCancelled判斷異步任務(wù)是否取消,isDone判斷任務(wù)是否執(zhí)行結(jié)束

    @Test
    public void testDealHaveReturnTask() throws Exception {

        Future future = asyncTask.dealHaveReturnTask();
        log.info("begin to deal other Task!");
        while (true) {
            if(future.isCancelled()){
                log.info("deal async task is Cancelled");
                break;
            }
            if (future.isDone() ) {
                log.info("deal async task is Done");
                log.info("return result is " + future.get());
                break;
            }
            log.info("wait async task to end ...");
            Thread.sleep(1000);
        }
    }

日志打印如下,我們可以看出任務(wù)一直在等待異步任務(wù)執(zhí)行完畢,用future.get()來獲取異步任務(wù)的返回結(jié)果

begin to deal other Task!
wait async task to end ...
wait async task to end ...
wait async task to end ...
wait async task to end ...
deal async task is Done
return result is {"thread":"AsyncExecutorThread-1","time":1499752617330}
4.異常處理

我們可以實(shí)現(xiàn)AsyncConfigurer接口,也可以繼承AsyncConfigurerSupport類來實(shí)現(xiàn)
在方法getAsyncExecutor()中創(chuàng)建線程池的時(shí)候,必須使用 executor.initialize(),
不然在調(diào)用時(shí)會(huì)報(bào)線程池未初始化的異常。
如果使用threadPoolTaskExecutor()來定義bean,則不需要初始化

@Configuration
@EnableAsync
@Slf4j
public class AsyncConfig implements AsyncConfigurer {

//    @Bean
//    public ThreadPoolTaskExecutor threadPoolTaskExecutor(){
//        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//        executor.setCorePoolSize(10);
//        executor.setMaxPoolSize(100);
//        executor.setQueueCapacity(100);
//        return executor;
//    }

    @Override
    public Executor getAsyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setMaxPoolSize(100);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("AsyncExecutorThread-");
        executor.initialize(); //如果不初始化,導(dǎo)致找到不到執(zhí)行器
        return executor;
    }
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }
}

異步異常處理類:

@Slf4j
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
        log.info("Async method: {} has uncaught exception,params:{}", method.getName(), JSON.toJSONString(params));

        if (ex instanceof AsyncException) {
            AsyncException asyncException = (AsyncException) ex;
            log.info("asyncException:{}",asyncException.getErrorMessage());
        }

        log.info("Exception :");
        ex.printStackTrace();
    }
}

異步處理異常類:

@Data
@AllArgsConstructor
public class AsyncException extends Exception {
    private int code;
    private String errorMessage;
}

在無返回值的異步調(diào)用中,異步處理拋出異常,AsyncExceptionHandler的handleUncaughtException()會(huì)捕獲指定異常,原有任務(wù)還會(huì)繼續(xù)運(yùn)行,直到結(jié)束。

在有返回值的異步調(diào)用中,異步處理拋出異常,會(huì)直接拋出異常,異步任務(wù)結(jié)束,原有處理結(jié)束執(zhí)行。

大家可以關(guān)注我的公眾號(hào):不知風(fēng)在何處,相互溝通,共同進(jìn)步。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/67362.html

相關(guān)文章

  • springboot 異步調(diào)用

    摘要:異步程序在順序執(zhí)行時(shí),不等待異步調(diào)用的語句返回結(jié)果就執(zhí)行后面的程序當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果。 同步 程序按照定義順序依次執(zhí)行,每一行程序都必須等待上一行程序執(zhí)行完成之后才能執(zhí)行,就是在發(fā)出一個(gè)功能調(diào)用時(shí),在沒有得到結(jié)果之前,該調(diào)用就不返回。 異步 程序在順序執(zhí)行時(shí),不等待異步調(diào)用的語句返回結(jié)果就執(zhí)行后面的程序,當(dāng)一個(gè)異步過程調(diào)用發(fā)出后,調(diào)用者不能立刻得到結(jié)果。 ...

    weij 評(píng)論0 收藏0
  • springboot 異步回調(diào)

    摘要:定義異步方法,使用來返回異步調(diào)用的結(jié)果開始做任務(wù)一完成任務(wù)一,當(dāng)前線程,耗時(shí)毫秒任務(wù)一完成開始做任務(wù)二完成任務(wù)二,當(dāng)前線程,耗時(shí)毫秒任務(wù)二完成開始做任務(wù)三完成任務(wù)三,當(dāng)前線程,耗時(shí)毫秒任務(wù)三完成調(diào)用執(zhí)行異步回調(diào)異步回調(diào)結(jié)束調(diào)用結(jié)果開 定義異步方法,使用Future來返回異步調(diào)用的結(jié)果 @Async public Future firstTask() throws Int...

    BingqiChen 評(píng)論0 收藏0
  • Springboot對(duì)多線程的支持詳解

    摘要:對(duì)多線程的支持詳解這兩天看阿里的開發(fā)手冊(cè),到多線程的時(shí)候說永遠(yuǎn)不要用這種方式來使用多線程。在使用線程池的大多數(shù)情況下都是異步非阻塞的。二配置類配置類代碼如下下午解讀利用來開啟對(duì)于異步任務(wù)的支持配置類實(shí)現(xiàn)接口,返回一個(gè)線程池對(duì)象。 Springboot對(duì)多線程的支持詳解 這兩天看阿里的JAVA開發(fā)手冊(cè),到多線程的時(shí)候說永遠(yuǎn)不要用 new Thread()這種方式來使用多線程。確實(shí)是這樣的...

    adie 評(píng)論0 收藏0
  • springboot配置線程池使用多線程插入數(shù)據(jù)

    摘要:最開始是使用的正常的普通方式去寫入,但是量太大了,所以就嘗試使用多線程來寫入。下面我們就來介紹一下怎么使用多線程進(jìn)行導(dǎo)入。配置線程池我們需要?jiǎng)?chuàng)建一個(gè)類來設(shè)置線程池的各種配置。它可以使主線程一直等到所有的子線程執(zhí)行完之后再執(zhí)行。 前言: 最近在工作中需要將一大批數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫中,因?yàn)榉N種原因這些數(shù)據(jù)不能使用同步數(shù)據(jù)的方式來進(jìn)行復(fù)制,而是提供了一批文本,文本里面有很多行url地址,需要的...

    wenshi11019 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

gityuan

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<