春天3.X - 由任务执行同时调用@Async方法不 [英] Spring 3.x - @Async methods not called concurrently by task executor

查看:124
本文介绍了春天3.X - 由任务执行同时调用@Async方法不的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现我的服务类并发方法调用。

I'm trying to implement concurrent method invocation in my Service class.

我在我的服务类注释为@Async一些方法,我试图同时调用这些方法。但这些方法在执行顺序

I've some methods annotated as @Async in my service class and I'm trying to call all these methods concurrently. But the methods are executing sequentially.

这是我的服务类(虚拟):

This is my service class(dummy):

@Service public class TestService {

public SomeDataType getSOmeDataType() {
        try {
            List<DataType> a = retrieveDataA().get();
            List<DataType> b = retrieveDataB().get();
            List<DataType> c = retrieveDataC().get();
            List<DataType> d = retrieveDataD().get();
            List<DataType> e = retrieveDataE().get();           
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        catch (ExecutionException e) {
            e.printStackTrace();
        }
        return referralDetailsReferenceData;
    }

@Async 
    private Future<List<DataType>> retrieveDataA() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataB() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataC() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataD() {
        //method logic
    }

@Async 
    private Future<List<DataType>> retrieveDataE() {
        //method logic
    }

这是我的Spring配置:

This is my spring config:

<bean id="executorService" class="java.util.concurrent.Executors" factory-method="newFixedThreadPool">
    <constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

在执行getSomeDataType的方法依次调用。

When "getSomeDataType" is executed the methods are invoked sequentially.

我是新来@Async和春季并发执行,所以我知道我在做一些愚蠢的。但我无法弄清楚。

I'm new to @Async and concurrent execution in Spring, so I'm sure I'm doing something silly. But I'm not able to figure it out.

任何建议是高度AP preciated。

Any suggestions is highly appreciated.

推荐答案

的问题是,你在网络内部调用方法,所以他们不是代理。对于 @Async 来工作,你需要从你的应用程序上下文检索对象并调用检索到的副本的方法。调用它在内部将无法工作。

The issue is that you're calling the methods internally so they're not proxied. For the @Async to work you need to retrieve the object from your application context and invoke the methods on the retrieved copy. Invoking it internally will not work.

如果你尝试调用内部 @Transactional 方法同样的事情发生。请参阅注意:部分在的<一个结束href=\"http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#transaction-declarative-annotations\">Spring文档解释 @Transactional 了解详情。

The same thing happens if you try to invoke internal @Transactional methods. See the Note: section at the end of the Spring docs explaining @Transactional for details.

此外,你立即调用获得()未来返回值的方式不正确。如果你希望他们并行发生,你应该提交的所有的任务然后检索通过。获得每一个()

Additionally, the way you're immediately calling .get() on the Future return values is incorrect. If you want them to happen in parallel you should submit all the tasks then retrieve each one via .get().

通常的方法是处理代理问题是创建一个单独的服务类获得 TestService的注入,并调用 @Async 服务方法直接:

The usual approach is to handle the proxying issue is to create a separate service class that gets TestService injected into it and calls the @Async service methods directly:

@Service public class TestServiceHelper {
    @Autowired
    TestService testService;

    public SomeDataType getSOmeDataType() {
        try {
            // Invoke all of them async:
            Future<List<DataType>> a = testService.retrieveDataA();
            Future<List<DataType>> b = testService.retrieveDataA();
            Future<List<DataType>> c = testService.retrieveDataA();
            Future<List<DataType>> d = testService.retrieveDataA();
            Future<List<DataType>> e = testService.retrieveDataA();

            // Wait for each sequentially:
            List<DataType> aList = a.get();
            List<DataType> bList = b.get();
            List<DataType> cList = c.get();
            List<DataType> dList = d.get();
            List<DataType> eList = e.get();

            // do work with lists here ...
        }
        catch (InterruptedException e) {
            e.printStackTrace();
        }
        catch (ExecutionException e) {
            e.printStackTrace();
        }
        return referralDetailsReferenceData;
    }
}

以上单独的服务豆(相当hackish的/不推荐!)另一种方法是对象注入自身并使用注射副本调用 @Async 方法

这篇关于春天3.X - 由任务执行同时调用@Async方法不的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆