1 异步线程池配置
@Slf4j
@Configuration
@EnableAsync
@EnableScheduling
public class TaskExecutorConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
// 核心线程数
taskExecutor.setCorePoolSize(5);
// 线程池最大线程数,默认:40000
taskExecutor.setMaxPoolSize(10);
// 线程队列最大线程数,默认:80000
taskExecutor.setQueueCapacity(10);
taskExecutor.setThreadNamePrefix("console-job-");
taskExecutor.initialize();
return taskExecutor;
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new ConsoleBizAsyncUncaughtExceptionHandler();
}
/**
* 控制台job定时任务业务异常
* @ControllerAdvice 无法全局捕获任务异常, 需要自定义异常处理
*/
class ConsoleBizAsyncUncaughtExceptionHandler implements AsyncUncaughtExceptionHandler {
@Override
public void handleUncaughtException(Throwable ex, Method method, Object... params) {
log.error("console job error, class:{}, method:{}, type:{}, exception:{}",
method.getDeclaringClass().getName(),
method.getName(),
ex.getClass().getName(),
ex.getMessage());
}
}
}
2 定时任务
@Slf4j
@Component
public class ScheduledJobTest {
public static int a = 1;
@Scheduled(fixedDelay = 1000)
@Async
public void a() throws InterruptedException {
log.info("a=" + a++);
Thread.sleep(100000);
}
}
3 测试
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class JobPoolTest {
@Autowired
private ScheduledJobTest scheduledJobTest;
@Test
public void test() throws InterruptedException{
Thread.sleep(3600 * 1000);
}
}
4 运行情况
2020-12-17 16:02:16.969 INFO 10252 --- [ console-job-1] com.job.ScheduledJobTest : a=1
2020-12-17 16:02:18.964 INFO 10252 --- [ console-job-3] com.job.ScheduledJobTest : a=3
2020-12-17 16:02:19.965 INFO 10252 --- [ console-job-4] com.job.ScheduledJobTest : a=4
2020-12-17 16:02:20.966 INFO 10252 --- [ console-job-5] com.job.ScheduledJobTest : a=5
2020-12-17 16:02:31.979 INFO 10252 --- [ console-job-6] com.job.ScheduledJobTest : a=6
2020-12-17 16:02:32.980 INFO 10252 --- [ console-job-7] com.job.ScheduledJobTest : a=7
2020-12-17 16:02:33.981 INFO 10252 --- [ console-job-8] com.job.ScheduledJobTest : a=8
2020-12-17 16:02:34.982 INFO 10252 --- [ console-job-9] com.job.ScheduledJobTest : a=9
2020-12-17 16:02:35.983 INFO 10252 --- [ console-job-10] com.job.ScheduledJobTest : a=10
2020-12-17 16:02:36.989 ERROR 10252 --- [ask-scheduler-3] o.s.integration.handler.LoggingHandler : org.springframework.core.task.TaskRejectedException: Executor [java.util.concurrent.ThreadPoolExecutor@4056319[Running, pool size = 10, active threads = 10, queued tasks = 10, completed tasks = 0]] did not accept task: org.springframework.aop.interceptor.AsyncExecutionInterceptor$1@6257338c
at org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor.submit(ThreadPoolTaskExecutor.java:323)
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java:273)
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:130)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656)
at com.lottop.job.ScheduledJobTest$$EnhancerBySpringCGLIB$$cd691536.a(<generated>)
at sun.reflect.GeneratedMethodAccessor125.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
消耗完成线程池后,完美挂掉。