@Async+Asyncconfigurer重新实现自定义线程池配置类。
@Configuration public class AsyncConfiguration implements AsyncConfigurer { @Bean("kingAsyncExecutor") public ThreadPoolTaskExecutor executor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); int corePoolSize = 10; executor.setCorePoolSize(corePoolSize); int maxPoolSize = 50; executor.setMaxPoolSize(maxPoolSize); int queueCapacity = 10; executor.setQueueCapacity(queueCapacity); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); String threadNamePrefix = "kingDeeAsyncExecutor-"; executor.setThreadNamePrefix(threadNamePrefix); executor.setWaitForTasksToCompleteOnShutdown(true); // 使用自定义跨线程的要求级别线程工厂类19 int awaitTerminationSeconds = 5; executor.setAwaitTerminationSeconds(awaitTerminationSeconds); executor.initialize(); return executor; } @Override public Executor getAsyncExecutor() { return executor(); } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (ex, method, params) -> ErrorLogger.getInstance().log(String.format(”执行异步任务的%s'", method), ex); } }
继承AsynconfigurerSupport@Configuration @EnableAsync class SpringAsyncConfigurer extends AsyncConfigurerSupport { @Bean public ThreadPoolTaskExecutor asyncExecutor() { ThreadPoolTaskExecutor threadPool = new ThreadPoolTaskExecutor(); threadPool.setCorePoolSize(3); threadPool.setMaxPoolSize(3); threadPool.setWaitForTasksToCompleteOnShutdown(true); threadPool.setAwaitTerminationSeconds(60 * 15); return threadPool; } @Override public Executor getAsyncExecutor() { return asyncExecutor; } @Override public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { return (ex, method, params) -> ErrorLogger.getInstance().log(String.format(”执行异步任务的%s'", method), ex);}}
由自定义Taskexecutor代替内置任务执行器@EnableAsync @Configuration public class TaskPoolConfig { @Bean(name = AsyncExecutionAspectSupport.DEFAULT_TASK_EXECUTOR_BEAN_NAME) public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(10); ////最大线程数 executor.setMaxPoolSize(20); ////队列容量 executor.setQueueCapacity(200); //活跃时间 executor.setKeepAliveSeconds(60); ///线程名前缀 executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } @Bean(name = "new_task") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); //核心线程池大小 executor.setCorePoolSize(10); ////最大线程数 executor.setMaxPoolSize(20); ////队列容量 executor.setQueueCapacity(200); //活跃时间 executor.setKeepAliveSeconds(60); ///线程名前缀 executor.setThreadNamePrefix("taskExecutor-"); executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor; } }
@Async失效- 使用static修改异步法
- 不使用@Component注释(或其他注释)导致spring无法扫描异步类
- 异步法不能与被调用的异步法相同
- 需要使用@Autowired或@resource等注解自动注入,不能手动注入new对象
- 如果使用SpringBoot框架,则必须在启动类中添加@Enableasync注释
@Async
注释的主要功能是实现异步法的调用。它可以将一种方法的执行委托给线程池中的线程进行异步执行,以免堵塞当前线程。
@Async
实际使用场景包括但不限于以下几个方面:
- 提高系统的并发性能力:通过异步化耗时的操作,可以提高系统的并发性能力。例如,在Web应用程序中,可以标记一些耗时的操作(如发送电子邮件、生成报告等)
@Async
,这样可以避免堵塞主线程,增加系统的吞吐量。 - 改善用户体验:可用于上传文件、数据处理等需要耗时操作的场景
@Async
实现异步处理,从而提升用户体验。用户可以在不等待耗时操作的情况下继续进行其他操作。 - 避免堵塞调用方:有时,调用方不希望等待方法的执行结果,而是希望立即返回。使用
@Async
该方法的执行可以转移到异步线程中,以避免阻塞调用方。 - 并行执行任务:在某些情况下,不等待执行结果,需要同时执行多个任务。使用
@Async
这些任务可以标记为异步法,它们可以并行执行,从而提高效率。
因为 Spring 同一类别中的方法调用不会通过代理对象实现异步执行。在同一类别中,方法调用是直接的普通方法调用,不会被代理拦截。
因此,如果一个被直接调用到同一类别中@Async
该方法将在当前线程中同步执行,而不是异步执行。这可能会影响您预期的异步执行效果。
为保证异步法的异步实施,应将异步法从同一类中剥离出来,并利用外部或其他类调用异步法。这样,Spring 异步法的调用将通过代理对象截获,并委托给异步线程池执行,从而达到异步执行的效果。
综上所述,如果异步法直接在同一类中调用,则该方法将在当前线程中同步执行。为了达到异步执行的效果,应通过外部或其他类别调用异步法。
@Async+自定义线程+配置类1、创建一个自定义的线程池,继承自己java.util.concurrent.ThreadPoolExecutor
或实现java.util.concurrent.Executor
接口,根据需要定制线程池的配置,如核心线程数、最大线程数、队列容量等。
import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class MyThreadPool { private ThreadPoolExecutor executor; public MyThreadPool() { int corePoolSize = 10; int maxPoolSize = 20; int queueCapacity = 50; executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(queueCapacity)); } public ThreadPoolExecutor getExecutor() { return executor; }}
2、Spring 在Boot的配置类别中创建一个@Bean
,返回自定义的线程池实例。
import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class AppConfig { @Bean public MyThreadPool myThreadPool() { return new MyThreadPool(); }}
3、使用需要异步执行的方法@Async
并使用注释executor
属性指定自定义的线程池。
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.annotation.Async;import org.springframework.stereotype.Service;@Servicepublic class MyService { private MyThreadPool myThreadPool; @Autowired public MyService(MyThreadPool myThreadPool) { this.myThreadPool = myThreadPool; } @Async(executor = "myThreadPool") public void asyncMethod() { // 异步执行的逻辑 // ... }}
手动控制线程池1、创建一个可以继承自定义的线程池java.util.concurrent.ThreadPoolExecutor
或实现java.util.concurrent.Executor
接口,根据需要定制线程池的配置。
import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;public class MyThreadPool { private ThreadPoolExecutor executor; public MyThreadPool() { int corePoolSize = 10; int maxPoolSize = 20; int queueCapacity = 50; executor = new ThreadPoolExecutor(corePoolSize, maxPoolSize, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(queueCapacity)); } public void execute(Runnable task) { executor.execute(task); }}
2、在需要异步执行的方法中,创建了实现的方法Runnable
并将接口的任务提交给自定义线程池执行。
public class MyClass { private MyThreadPool myThreadPool; public MyClass(MyThreadPool myThreadPool) { this.myThreadPool = myThreadPool; } public void myMethod() { // 实现Runnnable接口任务的创建 Runnable task = () -> { // 异步执行的逻辑 // ... }; // 提交给自定义线程池的任务 myThreadPool.execute(task); }}
