开启2025年的创作!大艺术家~
spring springboot test中使用new Thead或者for循环里包new Thread或者线程池ThreadPoolExecutor中执行对应逻辑,都有可能遇到一些错误,比如
纯手打日志
Exception in thread "Thread-48" org.springframework.core.task.TaskRejectedException:Executor [java.util.concurrent.ThreadPoolExecutorxxx[Shutting down,pool size=6,active threads=6,queued tasks=0,completed tasks=0]] did not accept task:
org.springframework.aop.interceptor.AsyncExecutionInterceptorxxxx
Caused by:java.util.concurrent.RejectedExecutionException:Task java.util.concurrent.FutureTaskxxx rejected from java.util.concurrent.TheadPoolExecutorxxx[Shutting down,pool size=6,active threads=6,queued tasks=0,completed tasks=0]
这种情况可能是尝试执行的任务被任务执行器拒绝。这通常发生在使用线程池执行异步任务时,当线程池已经达到最大线程数且队列也已满时,新的任务将无法被执行.
或者出现
Exception in thread "Thread-46" org.springframework.beans.factory.BeanCreationNotAllowedException:Error creating bean with name 'applicationTaskExecutor':Singleton bean creation not allowed while singletons of this factory are in destruction [Do not request a bean from a BeanFactory in a destory method implementation!]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:208)
这种情况可能是因为单例的bean在创建的时候,容器已经处于销毁阶段,生命周期不同,不允许再次创建生产Bean。主线程运行时,启动了线程池,线程池中的任务会加载bean,但因为异步原因,任务提交给线程池后,主线程结束了,开始销毁bean容器,而线程池任务有需要创建出bean,所以出现上述的异常情况。
详情可以参考:https://www.jb51.net/program/291919pdk.htm
我就是看了这篇文章察觉出些苗头的
最终的解决方法类似于:利用屏障等同步工具,等待线程执行完成后再退出主线程(其实没有解决,当时我觉得解决了,后来。。。发现这就是个diaomao问题)
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(4,8,60,TimeUnit.SECONDS,new LinkedBlockingDeque<>(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
int n=30;
final CountDownLatch countDownLatch = new CountDownLatch(n);
for(int i=0;i<n;i++) {
threadPoolExecutor.execute(()-> {
try{
...//业务代码
} catch(Exception e) {
e.printStackTrace();
} finally {
countDownLatch.countDown();
}
});
}
try{
countDownLatch.await();
} catch(InterruptedException e) {
throw new RuntimeException();
}
后来又在后面加了
try{
Thread.sleep(30000);
} catch(InterruptedException e) {
throw new RuntimeException();
}
可以了,但是不妙,很不妙
然后突然感到我的代码写错了位置,要搞多线程测试不要在test类中,生命周期太短了,主进程噶了就不让我子进程创建bean了
后来把这段代码放controller里搞了个测试方法,0问题!什么问题都没啦!我的两天!!!!QAQ
不喜欢把文章设为vip或者粉丝可见,这违背了我在csdn上发东西的初衷(初衷是为了听彩虹屁),要不以后去博客园发好了,还可以装修博客搞点样式