hi,你好!欢迎访问本站!登录
本站由网站地图腾讯云宝塔系统阿里云强势驱动
当前位置:首页 - 教程 - 杂谈 - 正文 君子好学,自强不息!

SpringBoot系列:Spring Boot异步挪用@Async

2019-11-18杂谈搜奇网68°c
A+ A-

在现实开辟中,有时刻为了及时处置惩罚请乞降举行相应,我们能够会多使命同时实行,或许先处置惩罚主使命,也就是异步挪用,异步挪用的完成有许多,比方多线程、定时使命、音讯行列等,

这一章节,我们就来讲讲@Async异步要领挪用。

一、@Async运用演示

@Async是Spring内置注解,用来处置惩罚异步使命,在SpringBoot中一样实用,且在SpringBoot项目中,除了boot自身的starter外,不须要分外引入依靠。

而要运用@Async,须要在启动类上加上@EnableAsync主动声明来开启异步要领。

@EnableAsync
@SpringBootApplication
public class SpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }

}

现假设有3个使命须要去处置惩罚,离别对应AsyncTask类的taskOne、taskTwo、taskThree要领,这里做了线程的sleep来模仿现实运转。

@Slf4j
@Component
public class AsyncTask {

    private Random random = new Random();
    
    public void taskOne() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命一实行完成耗时{}秒", (end - start)/1000f);
    }
    
    public void taskTwo() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命二实行完成耗时{}秒", (end - start)/1000f);
    }
    
    public void taskThree() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命三实行完成耗时{}秒", (end - start)/1000f);
    }

}

然后编写测试类,由于@Async注解须要再Spring容器启动后才见效,所以这里讲测试类放到了SpringBoot的test包下,运用了SpringBootTest。

@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
public class AsyncTaskTest {

    @Autowired
    private AsyncTask asyncTask;

    @Test
    public void doAsyncTasks(){
        try {
            long start = System.currentTimeMillis();
            asyncTask.taskOne();
            asyncTask.taskTwo();
            asyncTask.taskThree();
            Thread.sleep(5000);
            long end = System.currentTimeMillis();
            log.info("主程序实行完成耗时{}秒", (end - start)/1000f);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}

运转测试要领,能够在控制台看到使命一二三按递次实行,末了主程序完成,这和我们的预期一样,由于我们没有任何分外的处置惩罚,他们就是一般的要领,按编码递次顺次实行。

而假如要使使命并发实行,我们只须要在使命要领上运用@Async注解即可,须要注重的是@Async所润饰的要领不要定义为static范例,如许异步挪用不会见效。

@Slf4j
@Component
public class AsyncTask {

    private Random random = new Random();

    //@Async所润饰的函数不要定义为static范例,如许异步挪用不会见效
    @Async
    public void taskOne() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命一实行完成耗时{}秒", (end - start)/1000f);
    }

    @Async
    public void taskTwo() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命二实行完成耗时{}秒", (end - start)/1000f);
    }

    @Async
    public void taskThree() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命三实行完成耗时{}秒", (end - start)/1000f);
    }

}

然后我们在运转测试类,这个时刻输出能够就八门五花了,恣意使命都能够先实行完成,也有能够有的要领由于主程序封闭而没有输出。

二、Future猎取异步实行效果

上面演示了@Async,然则有时刻除了须要使命并发调度外,我们还须要猎取使命的返回值,且在多使命都实行完成后再终了主使命,这个时刻又该怎样处置惩罚呢?

在多线程里经由过程Callable和Future能够猎取返回值,这里也是相似的,我们运用Future返回要领的实行效果,AsyncResult 是Future的一个完成类。

@Slf4j
@Component
public class FutureTask {

    private Random random = new Random();

    //@Async所润饰的函数不要定义为static范例,如许异步挪用不会见效
    @Async
    public Future<String> taskOne() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命一实行完成耗时{}秒", (end - start)/1000f);
        return new AsyncResult <>("使命一Ok");
    }

    @Async
    public Future<String> taskTwo() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命二实行完成耗时{}秒", (end - start)/1000f);
        return new AsyncResult <>("使命二OK");
    }

    @Async
    public Future<String> taskThree() throws InterruptedException {
        long start = System.currentTimeMillis();
        Thread.sleep(random.nextInt(10000));
        long end = System.currentTimeMillis();
        log.info("使命三实行完成耗时{}秒", (end - start)/1000f);
        return new AsyncResult <>("使命三Ok");
    }

}

在AsyncResult中:

  • isDone()要领能够用于推断异步要领是不是实行完成,若使命完成,则返回true
  • get()要领可用于猎取使命实行后返回的效果
  • cancel(boolean mayInterruptIfRunning)可用于作废使命,参数mayInterruptIfRunning示意是不是许可作废正在实行却没有实行终了的使命,假如设置true,则示意能够作废正在实行过程当中的使命
  • isCancelled()要领示意使命是不是被作废胜利,假如在使命一般完成前被作废胜利,则返回 true
  • get(long timeout, TimeUnit unit)用来猎取实行效果,假如在指定时间内,还没猎取到效果,就直接返回null
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
public class AsyncTaskTest {

    @Autowired
    private FutureTask futureTask;

    @Test
    public void doFutureTasks(){
        try {
            long start = System.currentTimeMillis();
            Future <String> future1 = futureTask.taskOne();
            Future <String> future2 = futureTask.taskTwo();
            Future <String> future3 = futureTask.taskThree();
            //3个使命实行完成以后再实行主程序
            do {
                Thread.sleep(100);
            } while (future1.isDone() && future2.isDone() && future3.isDone());
            log.info("猎取异步要领的返回值:{}", future1.get());
            Thread.sleep(5000);
            long end = System.currentTimeMillis();
            log.info("主程序实行完成耗时{}秒", (end - start)/1000f);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

}

运转测试类,我们能够看到使命一二三异步实行了,主使命末了实行完成,而且能够猎取到使命的返回信息。

源码地点:https://github.com/imyanger/springboot-project/tree/master/p23-springboot-async

  选择打赏方式
微信赞助

打赏

QQ钱包

打赏

支付宝赞助

打赏

  移步手机端
SpringBoot系列:Spring Boot异步挪用@Async

1、打开你手机的二维码扫描APP
2、扫描左则的二维码
3、点击扫描获得的网址
4、可以在手机端阅读此文章
未定义标签

本文来源:搜奇网

本文地址:https://www.sou7.cn/282416.html

关注我们:微信搜索“搜奇网”添加我为好友

版权声明: 本文仅代表作者个人观点,与本站无关。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。请记住本站网址https://www.sou7.cn/搜奇网。

发表评论

选填

必填

必填

选填

请拖动滑块解锁
>>