- Main方法上开启异步:@EnableAsync
- (可选)配置线程池:配置ThreadPoolTaskExecutor,不配置则默认使用SimpleAsyncTaskExecutor
- 异步方法:@Async(“线程池名”)异步注解,放到方法上,表示调用该方法的线程与执行此方法的线程异步(调用线程与执行线程异步)
ThreadPoolTaskExecutor中的线程都是守护线程,用户线程执行完毕,杀死所有守护线程
ThreadPoolTaskExecutor对象调用shutdown()方法时是否等待任务执行完毕再尝试shutdown()
// true-等待正在执行任务的线程执行完毕再尝试shutdown(),false-不等待,直接shutdown(),以抛出java.lang.InterruptedException异常的方式shutdown // true-类似java线程池的shutdown(), false-类似java线程池的shutdownNow() threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
@Async使用注意
- @Async失效:static修饰异步方法(spring boot不能扫描到这个方法)
- @Async失效:一个类中的方法相互调用不会触发异步
- @Transactional失效:@Async方法上使用@Transactional
pom.xml
4.0.0 com.xcrj springbootbasic 1.0-SNAPSHOT 8 8 org.springframework.boot spring-boot-starter 2.7.1 org.springframework.boot spring-boot-starter-test 2.7.1 test junit junit RELEASE test
main @EnableAsync
package com.xcrj;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
// 开启异步
@EnableAsync
@SpringBootApplication
public class ApplicationMain {
public static void main(String[] args) {
SpringApplication.run(ApplicationMain.class, args);
System.out.println("启动");
}
}
configuration ThreadPoolTaskExecutor
package com.xcrj.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.ThreadPoolExecutor;
@Configuration
public class AsyncMeConfiguration {
// 配置线程池ThreadPoolTaskExecutor threadPoolTaskExecutor01
@Bean("threadPoolTaskExecutor01")
public ThreadPoolTaskExecutor getAsyncExecutor() {
ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
threadPoolTaskExecutor.setCorePoolSize(Runtime.getRuntime().availableProcessors());
threadPoolTaskExecutor.setMaxPoolSize(Runtime.getRuntime().availableProcessors() * 2);
threadPoolTaskExecutor.setQueueCapacity(200);
threadPoolTaskExecutor.setKeepAliveSeconds(10);
threadPoolTaskExecutor.setThreadNamePrefix("asyncMe");
threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
// true-等待正在执行任务的线程执行完毕再尝试shutdown(),false-不等待,直接shutdown(),以抛出java.lang.InterruptedException异常的方式shutdown
// true-类似java线程池的shutdown(), false-类似java线程池的shutdownNow()
threadPoolTaskExecutor.setWaitForTasksToCompleteOnShutdown(true);
threadPoolTaskExecutor.initialize();
return threadPoolTaskExecutor;
}
}
service方法 @Async
package com.xcrj.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class AsyncMeService {
// 使用threadPoolTaskExecutor01线程池中的线程异步执行service1
@Async("threadPoolTaskExecutor01")
public void service1() throws InterruptedException {
System.out.println("开始服务1");
// 执行任务耗时
Thread.sleep(5000);
System.out.println("结束服务1");
}
// 使用threadPoolTaskExecutor01线程池中的线程异步执行service2
@Async("threadPoolTaskExecutor01")
public void service2() throws InterruptedException {
System.out.println("开始服务2");
// 执行任务耗时
Thread.sleep(2000);
System.out.println("结束服务2");
}
}
test
package com.xcrj.service;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@SpringBootTest
@RunWith(SpringRunner.class)
public class TestAsyncMeService {
@Resource
private AsyncMeService asyncMeService;
@Resource(name = "threadPoolTaskExecutor01")
private ThreadPoolTaskExecutor threadPoolTaskExecutor;
@Test
public void testAsync() throws InterruptedException {
asyncMeService.service1();
asyncMeService.service2();
threadPoolTaskExecutor.shutdown();
// ThreadPoolTaskExecutor中的线程都是守护线程,用户线程执行完毕,杀死所有守护线程
Thread.sleep(10000);
System.out.println("结束test线程");
}
}



