【发布时间】:2018-10-23 01:00:29
【问题描述】:
Async 创建的线程第一次工作,第二次开始工作,它们似乎挂起。这是我的代码的样子 -
Sprint Boot Rest service {
-> invokes Class A @Async method {
-> invokes Class B @Async method
}
}
这个 rest 服务正在处理一个巨大的树,产生了很多线程。
这是 AsyncConfiguration 的样子:
setCorePoolSize - 1000
setMaxPoolSize - 20000
setQueueCapacity - 5000
setThreadNamePrefix - "ABCService"
我正在按照线程号记录线程,并且在第一次调用之前一切看起来都很干净。 activeCount:0, poolSize:0, maximumPoolSize:0, completedTaskCount:0, taskCount:0, remainingQueueCApacity:5000
在处理第一个请求时: activeCount:1000, poolSize:1000, maximumPoolSize:1000, completedTaskCount:6, taskCount:1782, remainingQueueCApacity:4224
处理第一个请求后: activeCount:0, poolSize:1000, maximumPoolSize:1000, completedTaskCount:2595, taskCount:2595, remainingQueueCApacity:5000
请求我的第二个请求后: activeCount:1000, poolSize:1000, maximumPoolSize:1000, completedTaskCount:2595, taskCount:4915, remainingQueueCApacity:3680
我认为线程挂起是因为线程似乎无法正常工作。另外,我没有看到 activeCount 有任何变化。
我在异步方法中有 try/catch 来处理任何异常。
这是我的异步方法定义如下:
@Async
public void foo(String , String , list, String , boolean ){
try {
List<CompletableFuture<String>> completableFutureList
for each item in list{
CompletableFuture<String> response = ClassB.bar(String , String , item, String , boolean);
completableFutureList.add(response);
}
CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()])).join();
.......
......
} catch (Throwable e) {
logger.error("Exception .... " );
}
}
class B method
@Async
public CompletableFuture<String> bar(String , String , item, String , boolean)){
try{
.....
......
}
catch(......) {
}
}
任何帮助将不胜感激。谢谢。
更新:
当我进行线程转储时,我看到所有线程都在等待(停车),如下所示。
“ABCService-26”#83 prio=5 os_prio=0 tid=0x00007f2ab829b800 nid=0x716d 等待条件 [0x00007f272ffc7000] java.lang.Thread.State: 等待(停车) 在 sun.misc.Unsafe.park(本机方法) - 停车等待 (a java.util.concurrent.CompletableFuture$Signaller) 在 java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) 在 java.util.concurrent.CompletableFuture$Signaller.block(CompletableFuture.java:1693) 在 java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323) 在 java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1729) 在 java.util.concurrent.CompletableFuture.join(CompletableFuture.java:1934) 在 com.abc.command.util.ClassA.foo(ClassA.java:106) 在 com.abc.command.util.ClassA.bar(ClassA.java:54) 在 com.abc.command.util.ClassA$$FastClassBySpringCGLIB$$b0eafa9.invoke() 在 org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) 在 org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:721) 在 org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) 在 org.springframework.aop.interceptor.AsyncExecutionInterceptor$1.call(AsyncExecutionInterceptor.java:115) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745)
【问题讨论】:
-
发一个A类和B类的模板好吗?这些方法返回无效吗?
-
您好 Mạnh Quyết Nguyễn,请查看帖子,我刚刚添加了方法...谢谢。
-
您在哪里记录这些池的属性?在 Spring Boot 服务内部?
-
是的。我将 ThreadPoolTaskExecutor 实例保存到配置类中的静态变量中,并在控制器类中使用该变量来记录池属性。
-
您是在调用 A.foo 后才登录的吗?你的第一个请求和第二个请求是一样的吧?
标签: spring multithreading asynchronous