在启动类或者线程池配置类上加注解 @EnableAsync
SpringBootApplication
@EnableAsync
public class XFBlogApplication {
public static void main(String[] args) {
SpringApplication.run(XFBlogApplication.class, args);
}
}
定义了线程池的属性类
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadPoolExecutor;
import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
@Configuration
public class ThreadPoolConfig {
public static final int corePoolSize = 50;
public static final int maxPoolSize = 200;
public static final int queueCapacity = 1000;
public static final int keepAliveSeconds = 300;
public static final String threadNamePrefix = "async-thread-";
@Bean(name = "threadPoolTaskExecutor")
public ThreadPoolTaskExecutor threadPoolTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setKeepAliveSeconds(keepAliveSeconds);
executor.setThreadNamePrefix(threadNamePrefix);
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return executor;
}
}
需要异步的方法上面加上 @Async
@Component
public class Test {
@Async("threadPoolTaskExecutor")
public void test(int i) throws Exception{
System.out.println("线程名称: " + Thread.currentThread().getName());
Thread.sleep(1000);
System.out.println("参数:"+i);
}
}
@Async注解失效的情况
-
异步方法使用static修饰。
-
异步类没有使用@Component注解(或其他注解)导致spring无法扫描到异步类(因为@Async是spring的注解)。
-
异步方法不能与异步方法在同一个类中。
-
类中需要使用@Autowired或@Resource等注解自动注入,不能自己手动new对象(就以上例来说,得注入service,而不能new)。
-
如果使用SpringBoot框架必须在启动类中/或者线程池固定属性类中,增加@EnableAsync注解。
-
在Async 方法上标注@Transactional是没用的。 在Async 方法调用的方法上标注@Transactional 有效。
-
调用被@Async标记的方法的调用者不能和被调用的方法在同一类中不然不会起作用。
-
使用@Async时要求是不能有返回值的不然会报错的 因为异步要求是不关心结果的。
解决事务和异步之间的矛盾
评论