首页 > 其他分享 >@Async实现异步任务

@Async实现异步任务

时间:2022-12-12 14:47:32浏览次数:60  
标签:异步 end System long currentTimeMillis start 任务 Async public

1、@Async是SpringBoot自带的一个执行步任务注解

@EnableAsync // 开启异步
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2、同步执行

定义几个方法,模拟耗时的操作

@Service
@Slf4j
public class ServiceDemoSync {
    public void taskOne() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    public void taskTwo() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    public void taskThere() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
    }
}

测试一下

/**
 * @author qbb
 */
@SpringBootTest
public class ServiceTestSync {

    @Autowired
    private ServiceDemoSync serviceDemoSync;

    @Test
    public void test01() throws Exception {
        long start = System.currentTimeMillis();
        serviceDemoSync.taskOne();
        serviceDemoSync.taskTwo();
        serviceDemoSync.taskThere();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

}

image

3、异步执行

@Service
@Slf4j
public class ServiceDemo {

    @Async
    public void taskOne() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    @Async
    public void taskTwo() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    @Async
    public void taskThere() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
    }
}
@SpringBootTest
public class ServiceTest {

    @Autowired
    private ServiceDemo serviceDemo;

    @Test
    public void test01() throws Exception {
        long start = System.currentTimeMillis();
        serviceDemo.taskOne();
        serviceDemo.taskTwo();
        serviceDemo.taskThere();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

}

image

4、使用自定义线程池

package com.qbb.service;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 自定义线程池
 */
@Configuration
public class ExecutorAsyncConfig {

    @Bean(name = "newAsyncExecutor")
    public Executor newAsync() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        taskExecutor.setCorePoolSize(2);
        // 线程池维护线程的最大数量,只有在缓冲队列满了以后才会申请超过核心线程数的线程
        taskExecutor.setMaxPoolSize(10);
        // 缓存队列
        taskExecutor.setQueueCapacity(2);
        // 允许的空闲时间,当超过了核心线程数之外的线程在空闲时间到达之后会被销毁
        taskExecutor.setKeepAliveSeconds(10);
        // 异步方法内部线程名称
        taskExecutor.setThreadNamePrefix("QIUQIU&LL-AsyncExecutor-");
        // 拒绝策略
        taskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        taskExecutor.initialize();
        return taskExecutor;
    }
}

定义线程任务

@Component
@Slf4j
public class FutureTaskExecutor {

    @Async(value = "newAsyncExecutor")
    public Future<String> taskOne() {
        return new AsyncResult<>(Thread.currentThread().getName() + "one 完成");
    }

    @Async(value = "newAsyncExecutor")
    public Future<String> taskTwo() {
        return new AsyncResult<>(Thread.currentThread().getName() + "two 完成");
    }

    @Async
    public Future<String> taskThree() {
        return new AsyncResult<>(Thread.currentThread().getName() + "three 完成");
    }
}

测试一下

/**
 * @author qbb
 */
@SpringBootTest
@Slf4j
public class FutureTaskTestExecutor {
    @Autowired
    private FutureTaskExecutor futureTaskExecutor;

    @Test
    public void runAsync() throws Exception {
        long start = System.currentTimeMillis();
        Future<String> taskOne = futureTaskExecutor.taskOne();
        Future<String> taskTwo = futureTaskExecutor.taskTwo();
        Future<String> taskThere = futureTaskExecutor.taskThree();

        while (true) {
            if (taskOne.isDone() && taskTwo.isDone() && taskThere.isDone()) {
                System.out.println("任务1返回结果={" + (taskOne.get()) + "},任务2返回结果={" + (taskTwo.get()) + "},任务3返回结果={" + (taskThere.get()) + "}");
                break;
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
    }
}

image

注意点:不生效的情况

1、@Async作用在static修饰的方法上不生效
image

2、调用异步任务的方法和异步方法在同一个类时不生效

@Service
@Slf4j
public class ServiceDemo {

    @Async
    public void taskOne() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务1执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    @Async
    public void taskTwo() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务2执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    @Async
    public void taskThere() throws Exception {
        long start = System.currentTimeMillis();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("线程:" + Thread.currentThread().getName() + "任务3执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

    @Test
    public void test01() throws Exception {
        long start = System.currentTimeMillis();
        taskOne();
        taskTwo();
        taskThere();
        Thread.sleep(200);
        long end = System.currentTimeMillis();
        System.out.println("总任务执行结束,总耗时={" + (end - start) + "} 毫秒");
    }

}

image

还是推荐使用CompletableFuture实现异步任务编排~~

标签:异步,end,System,long,currentTimeMillis,start,任务,Async,public
From: https://www.cnblogs.com/qbbit/p/16975977.html

相关文章

  • C# Task和async/await详解
    原文链接:https://blog.csdn.net/btfireknight/article/details/97766193一、什么是异步当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方......
  • Spring Boot整合Quartz实现定时任务表配置
    最近有个小项目要做,springmvc下的task设置一直不太灵活,因此在SpringBoot上想做到灵活的管理定时任务。需求就是,当项目启动的时候,如果有定时任务则加载进来,生成scheduler,通......
  • C#定时任务
     1///<summary>2///耗时计数器3///</summary>4publicclassElapsedTimer5{6//创建时默认为创建时间,这样不调用Sta......
  • java8 CompletableFuture异步调用与lamda结合
    前言:jdk1.8 lamda记录异步执行动作staticvoidthenApplyAsyncExample(){CompletableFuture<String>cf=CompletableFuture.completedFuture("message").thenApplyAs......
  • Awaitility同步异步工具介绍与RocketMQ中实战
    在编写测试用例的时候遇到有异步或者队列处理的时候经常会用到 ​​Thread.sleep()​​ 等待来进行测试。例如:​​DLedger​​ 测试选举的过程。当DLedgerLeader下线。......
  • python高性能异步爬虫
    目的:在爬虫中使用异步实现高性能的数据爬取操作。异步爬虫的方式:1、多线程,多进程(不建议):好处:可以为相关阻塞的操作单独开启线程,阻塞操作就可以异步执行。弊端:无法无限制的开......
  • 异步批处理教程
    书接上回大数据量、高并发业务怎么优化?(一)文章中介绍了异步批处理的三种方式,本文继续深入针对前两种进行讲解,并给出代码示例:一普通版本,采用阻塞队列 ArrayBlockingQue......
  • 进程和任务计划管理
    一、进程1.程序什么是程序?是一组计算机能识别和执行的指令,运行于电子计算机上,满足人们某种需求的信息化工具。用于描述进程要完成的功能,是控制进程执行的指令集。保......
  • 任务调度系统-业务线资源隔离
    问题背景最近注意到自己负责的一个任务调度集群碰到了计算资源业务线分配不均的问题(即业务线资源隔离没有做好):在任务高峰期,调度系统会将计算资源偏向分配给(执行耗时比较......
  • 《图形图像处理》课程项目设计任务书
    一、项目设计参考选题2022年图形图像处理项目选题推荐二、项目设计具体要求根据选定的主题,搜集素材完成项目设计、演示文稿制作、解说稿的书写、模拟演练,注意设计主题......