多线程的Spring @Async问题

时间:2018-05-13 02:13:51

标签: spring multithreading asynchronous

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,po​​olSize:1000,largestPoolSize:1000,completedTaskCount:6,taskCount:1782,remainingQueueCApacity:4224

处理完第一个请求后: activeCount:0,poolSize:1000,largestPoolSize:1000,completedTaskCount:2595,taskCount:2595,remainingQueueCApacity:5000

请求我的第二个请求后: activeCount:1000,po​​olSize: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)

1 个答案:

答案 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/