Async创建的线程第一次工作,第二次它们似乎挂起。这是我的代码的样子 -
Sprint Boot Rest service {
-> invokes Class A @Async method {
-> invokes Class B @Async method
}
}
这个休息服务正在处理一棵巨大的树,导致很多线程。
这是AsyncConfiguration的样子:
setCorePoolSize - 1000
setMaxPoolSize - 20000
setQueueCapacity - 5000
setThreadNamePrefix - "ABCService"
我在线程编号之后记录线程,并且在第一次调用之前一切看起来都很干净。 activeCount:0,poolSize:0,largestPoolSize:0,completedTaskCount:0,taskCount:0,remainingQueueCApacity:5000
处理第一个要求时: activeCount:1000,poolSize:1000,largestPoolSize:1000,completedTaskCount:6,taskCount:1782,remainingQueueCApacity:4224
处理完第一个请求后: activeCount:0,poolSize:1000,largestPoolSize:1000,completedTaskCount:2595,taskCount:2595,remainingQueueCApacity:5000
请求我的第二个请求后: activeCount:1000,poolSize:1000,largestPoolSize:1000,completedTaskCount:2595,taskCount:4915,remainingQueueCApacity:3680
我认为线程悬而未决,因为线程似乎无法正常工作。另外,我没有看到activeCount有任何变化。
我在异步方法中尝试/ catch来处理任何异常。
以下是我的Async方法定义:
@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(原生方法) - 停车等待&lt; 0x0000000745cf3198&gt; (java.util.concurrent.CompletableFuture $ Signaller) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.CompletableFuture $ Signaller.block(CompletableFuture.java:1693) at java.util.concurrent.ForkJoinPool.managedBlock(ForkJoinPool.java:3323) at java.util.concurrent.CompletableFuture.waitingGet(CompletableFuture.java:1729) at 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) at java.util.concurrent.FutureTask.run(FutureTask.java:266) 在java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor $ Worker.run(ThreadPoolExecutor.java:617) 在java.lang.Thread.run(Thread.java:745)
答案 0 :(得分:0)
问题似乎是CompletableFuture<String>
的JDK错误。解决方法是使用get(timeout)而不是join():
CompletableFuture<Void> future = CompletableFuture.allOf(completableFutureList.toArray(new CompletableFuture[completableFutureList.size()]));
future.get(executionTime, TimeUnit.MILLISECONDS);
这里有关于这个问题的更多细节......
https://bugs.openjdk.java.net/browse/JDK-8201576 https://crondev.wordpress.com/2017/01/23/timeouts-with-java-8-completablefuture-youre-probably-doing-it-wrong/