关于在springboot测试类中启动多线程出bug了这件事

开启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上发东西的初衷(初衷是为了听彩虹屁),要不以后去博客园发好了,还可以装修博客搞点样式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值