@Async实现异步任务

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实现异步任务编排~~

posted @   我也有梦想呀  阅读(65)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示